Notes on AtomGroup Travel - cortex-command-community/Cortex-Command-Community-Project GitHub Wiki
Pseudocode (somewhat) explaining AtomGroup::Travel (taken from AtomGroup.cpp)
Establish the travel trajectory of the origin of the AtomGroup during the time frame.
// SEGMENT LOOP ////////////////////////////////////////////////////////////////////////////////////////////
Loop through all segments between hits.
Loop through the Atoms.
Establish each Atom's added trajectory based on its offset and the MO's angular velocity.
Add the origin trajectory and added offset rotation trajectory for each Atom to get its total trajectory.
Reset the Atoms and init them for a new straight segment, using the calculated trajectory.
As a first step of segment, make the start step for all Atoms, the Atoms themselves should check if they are already on another MO, and if so, to remember to ignore that MO for the rest of this AtomGroup's travel.
Find out which Atom's total individual trajectory is the longest of them all, meaning its velocity is the greatest of all Atoms in this group during this travel.
Calculate and store that max velocity also highestVel = ((longestTraj / PPM) / traveltime).
Loop through the Atoms again.
Calculate and save the normalized velocity ratio of all Atoms by dividing their trajectory length with the longest. The fastest Atom(s) thus gets a ratio of 1.0, and all others get something 1.0 > x >= 0.0.
Somehow save each step ratio associated with its corresponding Atom.
// STEP LOOP ////////////////////////////////////////////////////////////////////////////////////////////
Loop through all the steps that the longest Atom trajectory has to take this AtomGroup travel.
Loop through the Atoms.
All Atoms whose (progress += velRatio) >= std::ceil(prevProgress), take a step to their next pixel locations and check for collisions. All others do nothing.
If any collision:
Add Atom to appropriate collision list (MO or terrain), and if MO, to save the MOID hit in the MO hit map, also.
If collision lists are empty:
Step loop continues to next iteration.
Else if MO hit list isn't empty:
Calculate the distributed mass for each MO hitting Atom this step, by diving total mass with total number of MO hitting Atoms.
For each MOID hit entry in the MO hit map
Step back all Atoms that previously took one during this step iteration.
Calculate the mass distribution denominator for the hit MO by taking the number of Atoms hitting it, and adjusting for the Atom resolution/density rating.
For each Atom hitting this specific MO
Tell the Atom to calculate the exact hit point and bitmap normal at that point on the MO that it's hitting
Calculate the Atom's velocity = highestVel * thisatom.velRatio.
Tell the Atom to then call CollideAtPoint on the MO that it hit, passing in hit point, bitmap normal, atom's velocity, the distributed mass of the atom, and the mass denominator of the hit MO.
Store the returned resulting impulse force vector in the list of impulse forces and their offsets.
Else if terrain hit list isn't empty:
First determine which Atoms will penetrate the terrain, by passing in their kinetic forces calculated with their distributed masses and individual velocities (highestVel * atom.velRatio).
Keep looping if not all terrain hitting Atoms penetrate, and keep increasing the distributed mass on them.
Do terrain bounce, if not all terrain hitting Atoms could penetrate, even when all mass was on them.
Back up all Atoms one step that previously took one during this step iteration
Else do terrain sink stuff, all Atoms who peeked steps, take them now.
Apply all collision responses to the state of the traveling MO, and start on the next segment iteration.