Tutorial - Callbacks
In Tutorial one we learned how to plug Newton into the graphic engine. We also manage to simulate a single rigid body, but what if we have a scene with thousands of physics entities. Scenes like this are very possible due the fact there is a lot of coherence in a physics environment. The action tends to be localized around the player and most of the objects in the scene are just sitting there waiting for the player of some other event to activate them.
The approach of tutorial one will require the application to re-define lots of its architecture in order to figure out what had changed after a physics updated call. It will probably have to modify its own data structure to keep shortcuts to bodies and joints.
Newton was designed to be as unintrusive as possible to the application. It was made to handle data sets of the order of several thousand bodies, without putting the burden of having to maintain these arrays onto the application. Newton uses an event driven paradigm to programming. When the application creates an object, it has the option to register a user data value and also some function pointers callbacks. Newton uses this function to communicate with the application every time some type of information has changed.
For this type of scenes we will also need some kind of graphic system to take care of the number of graphic objects in the scene. We will use a simple link list, we will add new objects to the end of the list and remove objects form the beginning.
Open up the project Tutorial 2 Using Callbacks, and open the file tutorial.cpp.
Find the function InitScene.
The first thing you will notice is that the function NewtonCreate is now passing two arguments. These are the pointers to the memory allocation and de-allocation functions
// Create the newton world nWorld = NewtonCreate (PhysicsAlloc, PhysicsFree);
Newton will call these functions whenever it needs memory and whenever some piece of memory needs to be freed. The application does not have to worry about memory be aligned; Newton takes care of that internally.
The allocation functions pass the memory size as an argument. The application can use this value to monitor how much memory the physics engine is using. Newton uses the concept of singleton internally, so it is possible that not all memory is de-allocated when the Newton world is destroyed. It is guarantied that all memory is de-allocated when the application terminates.
Next you will find that the pointer to the rigid body box now is a local variable. In fact there aren’t any pointers to any Newton object, except for world. It is difficult for beginner programmers to get used to not store the data with the application, but in time you will feel more comfortable with it. We are going to abuse the capability of Newton for scene management. We will save the Graphic object as the rigid body user data. And we will also add a destructor callback with the rigid body.
// Store the graphic object with the rigid body. NewtonBodySetUserData (floorBody, floor);
// Set a destructor for this rigid body NewtonBodySetDestructorCallback (floorBody, PhysicsBodyDestructor);
The following lines are similar to tutorial one, except that we are adding 100 stacks of 10 bodies each of boxes (1000 boxes). Note: if you do not have a high-end system you can just reduce any of the loop iteration indexes to something more manageable to you system.
Another thing different also is that we assign a force and torque callback as well as a transform call back function.
// Set the transform call back function NewtonBodySetTransformCallback (boxBody, PhysicsSetTransform); // Set the force and torque call back function NewtonBodySetForceAndTorqueCallback (boxBody, PhysicsApplyForceAndTorque);
With this the application main render loop now do not have to worry about looping trough the array of object to determine when an object has changed position.
The rest of the code is the same as tutorial one. When a body is about to be destroyed, it also destroys the graphic companion.
There are more objects in Newton that use the same callback mechanism: the materials, the joints, some special collisions geometry, the Newton world, and the iterator functions. We cannot cover all of then in one simple tutorial. But we will make a reference when any of these objects is introduced for the first time in a tutorial.
This is all for this tutorial.