Physical entities can be created via calls to the CreatePhysicalEntity
method of the physical world. It can create entities of the following types:
Entities can be created in either permanent or on-demand mode, which is specified by the parameter lifeTime (0 for permanent entities). In on-demand mode the placeholders of entities should be created first via CreatePhysicalPlaceholder
and then the physics will call the outer system back to create the full entity whenever some interaction is required in the bounding box of the placeholder.
If a non-permanent entity is not involved in any interactions (which also includes interactions with rays shot from outside) for the specified lifetime, it will be destroyed, with the placeholder remaining. The advantage is that placeholders require much less memory than full entities (ca. 70 vs. ca. 260 bytes). It is even possible for an outer system to support hierarchical placeholders, i.e. meta-placeholders that create other placeholders upon request.
Additionally, there is a sector-based on-demand physicalization (currently used for vegetation and optionally for brushes). It is activated after RegisterBBoxInPODGrid
is called. Entities are created and destroyed on a sector basis. The sector size is specified in SetupEntityGrid
.
In order to maintain associations with outside engine objects, physical entities store an additional void pointer and two 16-bit integers (pForeingData, iForeignData, and iForeignFlags). The entities themselves never modify these parameters, they are only set from outside. The intended usage is to store a pointer to the outside engine reference entity in pForeignData and to store the entity type, if applicable, in iForeignData. However, there are no restrictions that enforce this.
All physical entities have unique ids. It is possible to not specify an id during creation and let the physics engine generate one automatically, however, during serialization entities use these ids to save dependency information, so there should be a guarantee that entities will have the same ids when reading the saved state. It is also possible to set a new id later. Currently the physics engine uses a simple array to map ids to entity pointers, so using large id numbers will result in allocation of an equally large array.
DestroyPhysicalEntity
destroys a physical entity or suspends/restores it (if mode parameter is equal to 0, 1, and 2 correspondingly). Suspending an entity causes it to clear all its connections with other entities (this includes constraints) but without the actual deletion. Restoring this entity afterwards will not automatically restore all lost connections. Deleted entities are not destroyed immediately, they are put into a "recycle bin" instead (some entities that they had one-way connections with might need to remove references to them). Deleted entities with reference count <=0 are deleted from the recycle bin at the end of each TimeStep (this can also be forced by calling PurgeDeletedEntities
).
The physical world can have one special static terrain object (set up with SetHeightfieldData
) but it is also possible to create terrain geometry manually and add it to an entity in which case the number of terrains is unlimited.
For each material index, the physical world stores the friction coefficient, a bounciness (restitution) coefficient and some flags. Whenever two surfaces contact, the contact's friction and bounciness are computed as an average of these values of both surfaces. The flags only affect raytracing (see below).
Internally, physical entities are grouped by their simulation class. It is important to know this because some interface functions, such as ray tracing and querying entities in an area, allow filtering entities by this type. The types are: