add testCollisions method for manual collision checking
This commit is contained in:
@@ -1042,7 +1042,6 @@ namespace polyvox
|
||||
|
||||
_sceneManager->updateTransforms();
|
||||
_sceneManager->updateAnimations();
|
||||
_sceneManager->checkNonTransformableCollisions();
|
||||
|
||||
_cumulativeAnimationUpdateTime += tmr.elapsed();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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));
|
||||
Reference in New Issue
Block a user