FleX emits particle<->shape contacts to a contacts buffer
This is a fixed length equalling the number of particles, with offsets into a larger contacts buffer (accounting for max 4 contacts per particle)
We have to perform a linear search of the whole buffer to find all contacts
FleX provides a counts buffer which gives the collision counts per particle, so we definitely are O(N) for maximum number of particles, but not maximum number of contacts
Calling into Lua for every contact would be extremely slow (especially if doing anything intensive on particle contact)
Instead, we should aggregate the collisions by shape, and call a collision listener once per shape instead
Scope
todo - I don't know enough of how the binary module is structured to scope this properly @yogwoggf
The algorithm is roughly as follows:
Spawn a number of threads
On each thread:
Create an unordered map of shape IDs -> collision info
If shape IDs are roughly small and consecutive, could use an array of length MAX_SHAPE_ID
For each particle allocated to this thread
For each contact as given by counts[particleIndex]
Get shape ID, force vector, other userdata (e.g. particle type for portal gel type things and material properties)
If we don't have a particle userdata buffer yet to store the material and other things, this should be added
Aggregate the data with the thread-local shapeCollisionInfo[contactShapeId]
For force this should just be addition
For other props you may need a set of unique particle userdatas that were encountered (with e.g. a particle count assigned to each for weighted damage / other effects in lua)
After all threads complete, aggregate each thread's local aggregations together using the same algorithm as on the thread
Acceptance Criteria
Gelly provides addCollisionListener(function(entity, collisionDetails) end) and removeCollisionListener(myFunctionHandle) methods to Lua
Gelly calls each callback once per entity (shape) that was collided, with details of the collision passed as a table (force, array of particle types, etc.)
The collisions for a shape are aggregated
The performance of collison listeners are acceptable
It's possible to differentiate between particle types, to e.g. allow for portal gel presets to be created without having one or other spawned
Should be trivial if we already track materials on a per-particle basis
Otherwise we need a particle userdata buffer to be created and updated throughout the simulation
Context
counts
buffer which gives the collision counts per particle, so we definitely areO(N)
for maximum number of particles, but not maximum number of contactsScope
todo - I don't know enough of how the binary module is structured to scope this properly @yogwoggf
The algorithm is roughly as follows:
MAX_SHAPE_ID
counts[particleIndex]
shapeCollisionInfo[contactShapeId]
Acceptance Criteria
addCollisionListener(function(entity, collisionDetails) end)
andremoveCollisionListener(myFunctionHandle)
methods to LuaOther
No response