Data Access and Buffering
This chapter will discuss read/write access to PhysX objects which are in a scene, specifically the time frame when access is allowed and how/when the changes will take effect. For objects in different scenes or outside a scene, the restrictions are given in the multithreading guidelines in The Basics.
General Data Access Rules
It is important to distinguish two time slots for data access:
- After the call to PxScene::fetchResults() has returned and before the next PxScene::simulate() call (see figure below, blue area "1").
- After the call to PxScene::simulate() has returned and before the corresponding PxScene::fetchResults() call (see figure below, green area "2").
In the first time slot, the simulation is not running and there are no restrictions for reading or writing object properties. Changes to the position of an object, for example, are applied instantaneously and the next scene query or simulation step will take the new state into account.
In the second time slot the simulation is running and in the process, reading and changing the state of objects. Concurrent access from the user might corrupt the state of the objects or lead to data races or inconsistent views in the simulation code. Hence the simulation code's view of the objects is protected from API writes, and any attributes the simulation updates are buffered to allow API reads. The consequences will be discussed in detail in the next section.
Note that simulate() and fetchResults() are write calls on the scene, and as such it is illegal to access any object in the scene while these functions are running.
Double Buffering
While a simulation is running, PhysX supports read and write access to objects in the scene (with some exceptions, see further below). This includes adding/removing them to/from a scene.
From the user perspective, API changes are reflected immediately. For example, if the velocity of a rigid body is set and then queried, the new velocity will be returned. Similarly, if an object is created while the simulation is running, it can be accessed/modified as any other object. However, these changes are buffered so that the simulation code sees the object state as it was when PxScene::simulate() was called. For instance, changes to the filter data of an object while the simulation is running are ignored for collision pair generation of the running step, and will only affect for the next simulation step.
When PxScene::fetchResults() is called, any buffered changes are flushed: changes made by the simulation are reflected in API view of the objects, and API changes are made visible to the simulation code for the next step. User changes take precedence: for example, a user change to the position of an object while the simulation is running will overwrite the position which resulted from the simulation.
The delayed application of updates does not affect scene queries, which always take into account the latest changes.
Events involving removed objects
Deleting objects or removing them from the scene while the simulation is in process will affect the simulation events sent out at PxScene::fetchResults(). The behavior is as follows:
- PxSimulationEventCallback::onWake(), ::onSleep() events will not get fired if an object is involved which got deleted/removed during the running simulation.
- PxSimulationEventCallback::onContact(), ::onTrigger() events will get fired if an object is involved which got deleted/removed during the running simulation. The deleted/removed object will be marked as such (see PxContactPairHeaderFlag::eDELETED_ACTOR_0, PxContactPairFlag::eDELETED_SHAPE_0, PxTriggerPairFlag::eDELETED_SHAPE_TRIGGER). Furthermore, if PxPairFlag::eNOTIFY_TOUCH_LOST, ::eNOTIFY_THRESHOLD_FORCE_LOST events were requested for the pair containing the deleted/removed object, then these events will be created.
Support
Not all PhysX objects have full buffering support. Operations which can not run while the simulation is in process are mentioned in the API documentation and the SDK aborts such operations and reports an error. The most important exceptions are as follows:
- Particles: The particle bulk data can not be read or modified while the simulation is running, this includes operations like reading/writing particle positions/velocities, creating/deleting particles, adding forces, etc.
- Cloth: The only allowed double buffered operation is to create/delete a cloth and add/remove it to/from the scene.
Memory Considerations
The buffers to store the object changes while the simulation is running are created on demand. If memory usage concerns outweigh the advantage of reading/writing objects in parallel with simulation, do not write to objects while the simulation is running.