Tutorial - Getting Started
Tutorial 1: Getting started
This tutorial covers how to integrate Newton with your graphics engine.
Unpack the SDK, if you have not done it yet. Open Visual studio and find the project Tutorials.dsw and double click on it. Select the subproject Tutorial 1 - Getting started and make it the active project. Select the file Tutorial.cpp and double click to open it in the editor.
Go to the beginning of the file, where you willl find the include section. Add the following line:
#include "newton.h" #include "tutorial.h" #include "HiResTimer.h" #include "RenderPrimitive.h" #Include "Newton.h"
Now find the main function on that file. The first thing is the initialization of the graphics engine. In this case we encapsulated all OpenGl-initialization into one single function call. This represents your engine initialization for all major systems :
// Initialize opengl InitOpenGl (argc, argv, "Newton Getting Started", DrawScene, NULL, Keyboard);
Next you will see another call to initialize the scene :
// Create the physics scene. This represents your engine scene initialization InitScene();
Finally there is the OpenGL mainloop call. This represents your game engine's main loop.
Now find the function InitScene. This is where all the initialization of the physics engine happens.
For this tutorial we want to make the simplest possible physics scene, so we are going to create a rigid body box, suspended and spinning on the vacuum.
You will see :
// Create the newton world nWorld = NewtonCreate (NULL, NULL);
This makes an instance of the Newton world, and initializes all it's internal structures. Ignore the two arguments for now, as they will be explained in a later tutorial. We save the handle to the Newton world in a global variable.
Since it is not possible to get out of the OpenGl loop, we need to register an event to terminate the Newton world and all allocated resources. This is what the line atexit (Cleanup) does.
Next we need to create a rigid body, but for that we need to have the collision geometry first. (Rigid bodies must have collision geometry at all times).
So we create a box collision of the same size as the graphical box :
// Create the collision shape collision = NewtonCreateBox (nWorld, box.m_x * 2.0f, box.m_y * 2.0f, box.m_z * 2.0f, NULL);
The first argument to that call is the Newton world, followed by the box size. The last argument is the pointer to a transformation matrix used to offset the collision geometry from the origin of the rigid body. When Null, the box is placed at the origin of the body.
Now we create the rigid body and save it to a global variable :
// Create the rigid body rigidBodyBox = NewtonCreateBody (nWorld, collision);
After you are done using the collision object you must release it. Collision objects are the only objects in Newton that use reference count. This is done because other rigid bodies can share collision geometry. For example you can make several boxes of the same size and all of them may have the same collision geometry.
// Get rid of the collision NewtonReleaseCollision (nWorld, collision);
When Newton creates a rigid body, the mass is set to infinity, making the body static. We need to tell Newton we want this body to be dynamic. This is done by calling this piece of code :
// set the body mass and inertia NewtonBodySetMassMatrix (rigidBodyBox, 1.0f, 1.0f, 1.0f, 1.0f);
We also need to position this body in the world :
// Set the transformation matrix dMatrix matrix (box.GetMatrix()); matrix.m_posit.m_x = 0.0f; matrix.m_posit.m_y = 1.0f; matrix.m_posit.m_z = 0.0f; NewtonBodySetMatrix (rigidBodyBox, &matrix);
// Animate the body by setting the angular velocity dVector omega (1.0f, 1.0f, 1.0f); NewtonBodySetOmega (rigidBodyBox, &omega);
That’s all for initialization, now on to the main simulation loop :
Every frame OpenGl, or your engine, will make a call to the main simulation loop. For this tutorial this is the function DrawScene.
Notice that we need to get the elapsed time since the last update. This is done by the utility function :
// get the time step timeStep = timer.GetElapsedSeconds();
Next we call the NewtonUpdate to advance the world by this amount of time :
// update the Newton physics world NewtonUpdate (nWorld, timeStep);
Now we need to retrieve the transformation matrices of bodies, whose position changed during the world update call. For this example we are lucky as we only have one body :
// get the matrix from the rigid body dMatrix matrix; NewtonBodyGetMatrix(rigidBodyBox, &matrix);
Now we need to apply the transformation to the graphical body :
// Set the matrix of the visual body box.SetMatrix (matrix);
Finally we render the scene :
// Render the object glPushMatrix(); box.Render(); glPopMatrix();
And that covers the main loop.
The last thing is termination of the application. This happens when you hit the escape key or if you click on the close window button. Either case the function exit(0) is called. This function will call all termination events in reverse order. In our case we only have the Cleanup function that will destroy the Newton world.
To navigate the demo use the keyboard keys w, s, a, d, To change direction press the mouse button and move the mouse
This finishes this tutorial.