Repository navigation
Physics Objects
A physics object is a body the component simulates. Scripts create three kinds:
| Kind | Created with | Moves | Players see |
|---|---|---|---|
| Moving object | A3D_CreateObject, A3D_CreateSphere, A3D_CreateBox | Yes | A global object the component moves, or a streamer object |
| Static object | A3D_CreateStaticObject, A3D_CreateStaticBox, A3D_CreateStaticCylinder, A3D_CreateArea | No | Nothing |
| Zone | A3D_CreateZone, A3D_CreateZoneSphere | No | Nothing |
Moving objects fall, roll, bounce and push each other. Static objects stand still and stop them. Zones stop nothing and report the moving objects that enter and leave them.
The map of the game is in the world from the start, together with every player on foot, vehicle and actor.
Every kind shares one series of ids, tagged Physic:. INVALID_PHYSIC_ID means none. Ids are reused, so the next object created after a destroy may take the id of the destroyed one. Set the variables that kept an id to INVALID_PHYSIC_ID when the object goes.
An object belongs to the script that created it. Its callbacks are called in that script, and it is destroyed when that script unloads. Other scripts can still use its id.
Eight numbers can be kept on each object with A3D_SetExtra, such as the item it stands for or the player who threw it.
| Created with | Shape when moving | Shape when static |
|---|---|---|
| A model | The shape models.json gives it, or the convex hull of its collision, or its only sphere or box | The exact collision, with the surface of each part |
| A sphere, a box or a cylinder | That shape | That shape |
A convex hull wraps the model like a sheet of plastic, so a hollow model moves as a solid block. A model with no collision in the map database makes a moving object only through a shape in models.json, which the file of a release gives to balls, weapons and many items.
A moving object created with a model gets a global object of that model, which the component creates and moves. A global object shows in every virtual world, so for objects that belong to one world, create the body with the model -1 and give it a streamer object of that world with A3D_AttachDynamicObject.
Static objects and zones show nothing. Create the object players see yourself, at the same place.
The game knows nothing of the bodies. Players walk through static boxes and zones, and a ball that hits a player bounces off without pushing them.
The component never sends a position on every step. It sends a move, the way MoveObject does, aimed at where the body will be 3dandreas.sync_horizon seconds later, or where it stops when it slides to a halt, and turned the way its spin takes it, and works out where players see the object from it. When the shape of the body would meet something on the way, the move ends where it touches, at the time the body gets there, so the object players see never goes into the ground or a wall while the next move is on its way. When the body falls asleep, the object is put exactly where it rests.
A new move goes out when:
- the object players see strays from the body by more than the sync error, plus what the move it is on still has to close,
- the body brakes and will stop short of where the move takes the object,
- the rotation the move turns to no longer matches where the spin of the body takes it, by more than the angle that moves the far end of the object by the sync error, as when a crate lands and stops turning or a ball bounces,
- or the move has run its course while the body still moves.
A steady spin, such as a ball rolling, sends nothing more. A body in free fall is aimed along its fall, so a falling crate costs three or four updates a second. A body that stands still gets its move within a tenth of a second, so a crate that stops turning stops on the screen too, and a body that falls asleep glides to where it rests in a tenth of a second.
At most 3dandreas.max_updates updates go out a second, 1000 by default, the objects furthest from their bodies first. A client acknowledges every update, and past network.acks_limit, 3000 a second, open.mp warns and the game of that player falls behind and may crash, so a rain of hundreds of objects stays within it at the cost of looking less exact while it lasts.
The sync error is 3dandreas.sync_error, 0.1 metres by default, and A3D_SetSyncError changes it for one object. Every update reaches each player who sees the object, so objects that must look exact cost more. A ball flying straight costs a few updates a second, and a ball that bounces costs one at each bounce. A3D_GetStats counts the updates.
The world advances in fixed steps, 60 a second by default. Each tick of the server runs the steps due, at most four. Fast objects are swept along their path on every step, so they do not pass through thin walls.
An object falls asleep when it has moved less than about three centimetres a second for half a second. A sleeping object costs nothing and sends nothing. A3D_OnStopped is called then. A push, a hit by something awake or the removal of what it rests on wakes it again. An object that falls under 3dandreas.floor is stopped there.
| Property | Moving objects | Static objects and zones | Map, players, vehicles and actors |
|---|---|---|---|
| Friction | 0.5 |
0.5 |
0.2 |
| Bounce | 0.3 |
1.0 |
1.0 |
| Linear damping | 0.1 |
||
| Angular damping | 0.3 |
||
| Gravity | 9.81 |
||
| Collides with | A3D_COLLIDE_ALL |
Everything | Everything |
| Collision speed | 3dandreas.collision_speed |
||
| Sync error | 3dandreas.sync_error |
The friction of a contact is the square root of the product of both frictions, and its bounce the product of both bounces.
A moving object made by A3D_CreateObject takes the values of models.json for its model, and otherwise a mass from its volume and a friction and bounce from what its collision is made of. The defaults above are what is left when neither says anything.
- A player on foot is an upright capsule 1.8 metres tall and 0.7 wide, centred on their position. A player in a vehicle is inside the box of the vehicle.
- A vehicle is a box the size of its model, turned with the rotation the server knows.
3dandreas.vehiclesset tofalseleaves vehicles out. - An actor is a capsule like the one of a player.
They follow the server on every step. Moving objects bounce off them, and queries find them as A3D_HIT_PLAYER, A3D_HIT_VEHICLE and A3D_HIT_ACTOR. Their surfaces are PED for players and actors and CAR for vehicles.
A client sends its position about every 30 milliseconds and the simulation steps every 17, so between two positions a player or a vehicle is carried on by the velocity its client sent, for a tenth of a second at most. Moved straight to each position, it would jump and stand still in turn, and a crate it pushes would be kicked to twice the speed and slide off at every packet.
A player is a body of 80 kilograms driven to that place, never faster than the player walks plus one metre a second, and put there at once when it falls a metre behind. Crates caught between a player and something else push back instead of being thrown, and a player who walks into a pile pushes it like a person would. Vehicles and actors cannot be pushed at all.
An object of one world collides with the bodies of that world and with those of every world, -1. Players, vehicles and actors are in their own world. The map belongs to every world, except for the map objects removed from one world with A3D_RemoveBuilding.
- A3D_OnCollided: a moving object hit something at least as fast as its collision speed.
- A3D_OnStopped: a moving object came to rest.
- A3D_OnEntered and A3D_OnLeft: a moving object entered or left a zone.
Events are collected during a step and called after it, in the script that owns the object or the zone. Destroying objects inside them is safe.
3DAndreas 0.7.1 · Repository · Releases · MIT License
Guides
- Installation
- Configuration
- Physics objects
- Model settings
- World queries
- The screen
- Routes
- Navigation mesh
- Map database
- Coming from ColAndreas
- Performance
Reference
Functions