highfidelity/hifi — pull request #3922 by AndrewMeadows (2014-12-08 20:05:07+00:00)
Title: overhaul EntitySimulation API (and relay relevant EntityItem properties to simulation when they change)

This is a fix for the problem where changes to an EntityItem's simulation properties were not getting relayed to the EntitySimulation.

While I was at it I changed the API of the base EntityItem class to make it easier to add a Bullet-based simulation.

A summary of the important changes:

(1) I separated the notions of an EntityItem::update() and an EntityItem::simulation(). An EntityItem might need to be "updated" independently of its need to be "simulated". The only example of a EntityItem that needs a non-physical "update" right now is an animated model, however there may be other examples later. As such I had to split the concept of _lastSimulationTime out of _lastUpdateTime. There may still be a few confusions between these two values in the code, but we'll have to find and sort those out.

(2) EntitySimulation is still a pure virtual class, but much more of the default EntityItem lists management now lives in the base class. All derived classes now just need to implement four or five methods that are called internally inside the base class.

BTW: the EntitySimulation was made to help simplify the EntityTree (not all EntityTree instances need simulation, so it was not something that was fundamental to the class) and also for providing an API by which an EntityTree and a Bullet simulation can communicate changes. The important change required for Bullet is that the EntityTree will not be able to manually tell Bullet to take a simulation step -- the physics step will happen outside of the EntityTree update loop and incoming/outgoing changes will have to queue up on either side of that physics step.

(3) I've tried to make the meaning of EntityItem::_updateFlags more clear, so I changed the name of that member to _dirtyFlags and I've added a few comments in key places. In short, the _dirtyFlags indicate property changes that are inbound to the EntitySimulation, and are to be set whenever there are changes to from an "external" source (e.g. scripts and update packets from the EntityServer). Whenever _dirtyFlags are set the system will "harvest" those changes and feed them to the EntityServer so that it can update its own state at the right time.

(4) The main bug (script based changes were not reflected in the simulation) is fixed by making sure changes to physics properties set the proper _dirtyFlags -- as per item (3) above.

(5) I fixed a bug relating to how velocity damping is done in the simple ballistic extrapolation simulation. For large timesteps the damping could overshoot and cause large velocity values that are opposite to the original.

Note: when a damping factor is proportional to the velocity itself the solution to the differential equation is exponential decay, so I've changed the "meaning" of the VelocityDamping factor to be the "timescale of the exponential decay". Essentially this means that a timescale of 2.0 will reduce the velocity by 1/e every 2.0 seconds. Like the old damping calculations mine are only accurate for short timesteps (small fractions of the timescales themselves), however the good news is that my changes are stable for large timesteps and will compute large opposite velocities.