add flag for affectsCollidingTransform, add setParent method for transforms
This commit is contained in:
@@ -103,7 +103,9 @@ namespace polyvox
|
||||
const char *entityName);
|
||||
int getEntityCount(EntityId entity, bool renderableOnly);
|
||||
const char* getEntityNameAt(EntityId entity, int index, bool renderableOnly);
|
||||
void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(EntityId entityId));
|
||||
void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(EntityId entityId), bool affectsCollidingTransform);
|
||||
void removeCollisionComponent(EntityId entityId);
|
||||
void setParent(EntityId child, EntityId parent);
|
||||
|
||||
private:
|
||||
AssetLoader *_assetLoader = nullptr;
|
||||
|
||||
@@ -185,8 +185,9 @@ extern "C"
|
||||
FLUTTER_PLUGIN_EXPORT void set_recording_output_directory(void *const viewer, const char* outputDirectory);
|
||||
FLUTTER_PLUGIN_EXPORT void ios_dummy();
|
||||
FLUTTER_PLUGIN_EXPORT void flutter_filament_free(void *ptr);
|
||||
FLUTTER_PLUGIN_EXPORT void add_collision_component(void *const assetManager, EntityId entityId, void (*callback)(const EntityId entityId));
|
||||
FLUTTER_PLUGIN_EXPORT void add_collision_component(void *const assetManager, EntityId entityId, void (*callback)(const EntityId entityId), bool affectsCollidingTransform);
|
||||
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 assetManager, EntityId child, EntityId parent);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -13,57 +13,63 @@ namespace polyvox
|
||||
{
|
||||
|
||||
typedef void(*CollisionCallback)(int32_t entityId) ;
|
||||
class CollisionComponentManager : public utils::SingleInstanceComponentManager<filament::Aabb, CollisionCallback> {
|
||||
class CollisionComponentManager : public utils::SingleInstanceComponentManager<filament::Aabb, CollisionCallback, bool> {
|
||||
|
||||
const filament::TransformManager& _transformManager;
|
||||
public:
|
||||
CollisionComponentManager(const filament::TransformManager& transformManager) : _transformManager(transformManager) {}
|
||||
|
||||
std::vector<filament::math::float3> collides(filament::Aabb sourceBox, filament::math::float3 direction) {
|
||||
std::vector<filament::math::float3> collides(filament::Aabb sourceBox) {
|
||||
auto sourceCorners = sourceBox.getCorners();
|
||||
std::vector<filament::math::float3> collision_axes;
|
||||
std::vector<filament::math::float3> collisionAxes;
|
||||
for(auto it = begin(); it < end(); it++) {
|
||||
auto entity = getEntity(it);
|
||||
auto targetXformInstance = _transformManager.getInstance(entity);
|
||||
auto targetXform = _transformManager.getWorldTransform(targetXformInstance);
|
||||
auto targetBox = elementAt<0>(it).transform(targetXform);
|
||||
|
||||
bool collided = false;
|
||||
|
||||
// iterate over every vertex in the source AABB
|
||||
for(int i = 0; i < 8; i++) {
|
||||
// if the vertex has insersected with the target AABB
|
||||
if(targetBox.contains(sourceCorners.vertices[i]) < 0) {
|
||||
|
||||
collided = true;
|
||||
auto affectsCollidingTransform = elementAt<2>(it);
|
||||
if(affectsCollidingTransform) {
|
||||
auto intersecting = sourceCorners.vertices[i];
|
||||
auto min = targetBox.min;
|
||||
auto max = targetBox.max;
|
||||
|
||||
auto intersecting = sourceCorners.vertices[i];
|
||||
auto min = targetBox.min;
|
||||
auto max = targetBox.max;
|
||||
float xmin = min.x - intersecting.x;
|
||||
float ymin = min.y - intersecting.y;
|
||||
float zmin = min.z - intersecting.z;
|
||||
float xmax = intersecting.x - max.x;
|
||||
float ymax = intersecting.y - max.y;
|
||||
float zmax = intersecting.z - max.z;
|
||||
|
||||
float xmin = min.x - intersecting.x;
|
||||
float ymin = min.y - intersecting.y;
|
||||
float zmin = min.z - intersecting.z;
|
||||
float xmax = intersecting.x - max.x;
|
||||
float ymax = intersecting.y - max.y;
|
||||
float zmax = intersecting.z - max.z;
|
||||
|
||||
auto maxD = std::max(xmin,std::max(ymin,std::max(zmin,std::max(xmax,std::max(ymax,zmax)))));
|
||||
filament::math::float3 axis;
|
||||
if(maxD == xmin) {
|
||||
axis = {-1.0f,0.0f, 0.0f};
|
||||
} else if(maxD == ymin) {
|
||||
axis = {0.0f,-1.0f, 0.0f};
|
||||
} else if(maxD == zmin) {
|
||||
axis = {0.0f,0.0f, -1.0f};
|
||||
} else if(maxD == xmax) {
|
||||
axis = {1.0f,0.0f, 0.0f};
|
||||
} else if(maxD == ymax) {
|
||||
axis = {0.0f,1.0f, 0.0f};
|
||||
} else {
|
||||
axis = { 0.0f, 0.0f, 1.0f};
|
||||
auto maxD = std::max(xmin,std::max(ymin,std::max(zmin,std::max(xmax,std::max(ymax,zmax)))));
|
||||
filament::math::float3 axis;
|
||||
if(maxD == xmin) {
|
||||
axis = {-1.0f,0.0f, 0.0f};
|
||||
} else if(maxD == ymin) {
|
||||
axis = {0.0f,-1.0f, 0.0f};
|
||||
} else if(maxD == zmin) {
|
||||
axis = {0.0f,0.0f, -1.0f};
|
||||
} else if(maxD == xmax) {
|
||||
axis = {1.0f,0.0f, 0.0f};
|
||||
} else if(maxD == ymax) {
|
||||
axis = {0.0f,1.0f, 0.0f};
|
||||
} else {
|
||||
axis = { 0.0f, 0.0f, 1.0f};
|
||||
}
|
||||
collisionAxes.push_back(axis);
|
||||
}
|
||||
collision_axes.push_back(axis);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(collision_axes.size() > 0) {
|
||||
if(collided) {
|
||||
auto callback = elementAt<1>(it);
|
||||
if(callback) {
|
||||
callback(utils::Entity::smuggle(entity));
|
||||
@@ -71,7 +77,7 @@ class CollisionComponentManager : public utils::SingleInstanceComponentManager<f
|
||||
}
|
||||
}
|
||||
|
||||
return collision_axes;
|
||||
return collisionAxes;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1163,7 +1163,19 @@ namespace polyvox
|
||||
tm.setTransform(tm.getInstance(inst->getRoot()), transform);
|
||||
}
|
||||
|
||||
void AssetManager::addCollisionComponent(EntityId entityId, void(*onCollisionCallback)(EntityId entityId)) {
|
||||
void AssetManager::setParent(EntityId childEntityId, EntityId parentEntityId) {
|
||||
auto& tm = _engine->getTransformManager();
|
||||
const auto child = Entity::import(childEntityId);
|
||||
const auto parent = Entity::import(parentEntityId);
|
||||
|
||||
const auto& parentInstance = tm.getInstance(parent);
|
||||
const auto& childInstance = tm.getInstance(child);
|
||||
tm.setParent(childInstance, parentInstance);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void AssetManager::addCollisionComponent(EntityId entityId, void(*onCollisionCallback)(EntityId entityId), bool affectsCollidingTransform) {
|
||||
std::lock_guard lock(_mutex);
|
||||
const auto &pos = _entityIdLookup.find(entityId);
|
||||
if (pos == _entityIdLookup.end())
|
||||
@@ -1176,6 +1188,7 @@ namespace polyvox
|
||||
auto collisionInstance = _collisionComponentManager->addComponent(asset.asset->getRoot());
|
||||
_collisionComponentManager->elementAt<0>(collisionInstance) = asset.asset->getInstance()->getBoundingBox();
|
||||
_collisionComponentManager->elementAt<1>(collisionInstance) = onCollisionCallback;
|
||||
_collisionComponentManager->elementAt<2>(collisionInstance) = affectsCollidingTransform;
|
||||
|
||||
}
|
||||
|
||||
@@ -1227,18 +1240,16 @@ namespace polyvox
|
||||
auto bb = asset.asset->getBoundingBox();
|
||||
auto transformedBB = bb.transform(transform);
|
||||
|
||||
auto collisions = _collisionComponentManager->collides(transformedBB, relativeTranslation);
|
||||
auto collisionAxes = _collisionComponentManager->collides(transformedBB);
|
||||
|
||||
Log("%d collisions", collisions.size());
|
||||
if(collisions.size() == 1) {
|
||||
auto globalAxis = collisions[0];
|
||||
if(collisionAxes.size() == 1) {
|
||||
auto globalAxis = collisionAxes[0];
|
||||
globalAxis *= norm(relativeTranslation);
|
||||
auto newRelativeTranslation = relativeTranslation + globalAxis;
|
||||
// Log("Collision axis global : %f %f %f relativeTranslation %f %f %f relativeTranslation (after subtracting global collision vector) %f %f %f", globalAxis.x, globalAxis.y, globalAxis.z, relativeTranslation.x, relativeTranslation.y, relativeTranslation.z, newRelativeTranslation.x, newRelativeTranslation.y, newRelativeTranslation.z);
|
||||
translation -= relativeTranslation;
|
||||
translation += newRelativeTranslation;
|
||||
transform = composeMatrix(translation, rotation, scale);
|
||||
} else if(collisions.size() > 1) {
|
||||
} else if(collisionAxes.size() > 1) {
|
||||
translation -= relativeTranslation;
|
||||
transform = composeMatrix(translation, rotation, scale);
|
||||
}
|
||||
|
||||
@@ -547,8 +547,8 @@ extern "C"
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void add_collision_component(void *const assetManager, EntityId entityId, void (*onCollisionCallback)(const EntityId entityId)) {
|
||||
((AssetManager*)assetManager)->addCollisionComponent(entityId, onCollisionCallback);
|
||||
FLUTTER_PLUGIN_EXPORT void add_collision_component(void *const assetManager, EntityId entityId, void (*onCollisionCallback)(const EntityId entityId), bool affectsCollidingTransform) {
|
||||
((AssetManager*)assetManager)->addCollisionComponent(entityId, onCollisionCallback, affectsCollidingTransform);
|
||||
}
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT EntityId create_geometry(void *const viewer, float* vertices, int numVertices, uint16_t* indices, int numIndices, const char* materialPath) {
|
||||
@@ -560,4 +560,8 @@ extern "C"
|
||||
return Entity::smuggle(entity);
|
||||
}
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void set_parent(void *const assetManager, EntityId child, EntityId parent) {
|
||||
((AssetManager*)assetManager)->setParent(child, parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -564,11 +564,17 @@ abstract class FilamentController {
|
||||
/// If there is a collision between the controlled entity and [collidableEntity], the transform will not be updated.
|
||||
///
|
||||
Future addCollisionComponent(FilamentEntity collidableEntity,
|
||||
{void Function(int entityId)? callback});
|
||||
{void Function(int entityId)? callback,
|
||||
bool affectsCollingTransform = false});
|
||||
|
||||
///
|
||||
/// Creates a (renderable) entity with the specified geometry and adds to the scene.
|
||||
///
|
||||
Future createGeometry(
|
||||
List<double> vertices, List<int> indices, String? materialPath);
|
||||
|
||||
///
|
||||
/// Sets the parent transform of [child] to the transform of [parent].
|
||||
///
|
||||
Future setParent(FilamentEntity child, FilamentEntity parent);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import 'package:flutter_filament/filament_controller.dart';
|
||||
import 'package:flutter_filament/animations/animation_data.dart';
|
||||
import 'package:flutter_filament/generated_bindings.dart';
|
||||
import 'package:flutter_filament/hardware/hardware_keyboard_listener.dart';
|
||||
import 'package:flutter_filament/hardware/hardware_keyboard_poll.dart';
|
||||
|
||||
import 'package:flutter_filament/rendering_surface.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
@@ -1391,7 +1391,8 @@ class FilamentControllerFFI extends FilamentController {
|
||||
|
||||
@override
|
||||
Future addCollisionComponent(FilamentEntity entity,
|
||||
{void Function(int entityId)? callback}) async {
|
||||
{void Function(int entityId)? callback,
|
||||
bool affectsCollingTransform = false}) async {
|
||||
if (_assetManager == null) {
|
||||
throw Exception("AssetManager must be non-null");
|
||||
}
|
||||
@@ -1400,9 +1401,11 @@ class FilamentControllerFFI extends FilamentController {
|
||||
if (callback != null) {
|
||||
var ptr =
|
||||
NativeCallable<Void Function(Int32 entityId)>.listener(callback);
|
||||
add_collision_component(_assetManager!, entity, ptr.nativeFunction);
|
||||
add_collision_component(
|
||||
_assetManager!, entity, ptr.nativeFunction, affectsCollingTransform);
|
||||
} else {
|
||||
add_collision_component(_assetManager!, entity, nullptr);
|
||||
add_collision_component(
|
||||
_assetManager!, entity, nullptr, affectsCollingTransform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1440,4 +1443,12 @@ class FilamentControllerFFI extends FilamentController {
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@override
|
||||
Future setParent(FilamentEntity child, FilamentEntity parent) async {
|
||||
if (_assetManager == null) {
|
||||
throw Exception("Asset manager must be non-null");
|
||||
}
|
||||
set_parent(_assetManager!, child, parent);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user