A complete engine must keep track of a group of particles, the forces applied to them, and handle collisions between them:
class ParticleWorld {
Particles;
resolver;
ContactGenerators;
contacts;
maxContacts;
iterations;
// Create a new Particle simulator
constructor(maxContacts, iterations = 2 * maxContacts){
this.maxContacts = maxContacts;
this.iterations = iterations;
}
// Initialize the world for a new frame
startFrame(){
for(var p of this.Particles){
// Reset particles accumulators
p.clearAccumulators();
// Calculate derived data (TODO later)
// p.calculateDerivedData();
}
}
// Add and count the generated contacts
generateContacts(){
var limit = this.maxContacts;
var nextContact = this.contacts;
for(var g of this.contactGenerators){
var used = g.addContact(nextContact, limit);
limit -= used;
nextContact += used;
// We’re missing contacts
if(limit <= 0) break;
}
// Return the number of contacts used
return maxContacts - limit;
}
// Integrate all particles
integrate(duration){
for(var p of this.Particles){
// Integrate the particle by the given duration
p.integrate(duration);
}
}
// Process all the physics
runPhysics(duration){
// Apply the force generators
//registry.updateForces(duration);
// Then integrate the objects
this.integrate(duration);
// Generate contacts
var usedContacts = this.generateContacts();
// And process them
if(usedContacts){
this.resolver.setIterations(this.iterations);
this.resolver.resolveContacts(this.contacts, usedContacts, duration);
}
}
}
class ParticleContactGenerator {
// Fills a contact structure
addContact(contact, limit = 0){
}
}
// Example of game loop
loop = () => {
setInterval(()=>{
// Prepare world
world.startFrame();
// Update graphics, characters, ...
// Update physics
world.runPhysics(16);
},16);
}
See bridge and platform demos (can't implement them yet as they involve non-particle collisions...)