Moderators: Sascha Willems, walaber
/*
Newton Physics Engine (NPE) Tutorial Code v0.1
+ Simple GLUT "Hello World" physics engine application.
+ A number of uniform spheres will be dropped randomly
+ from space onto a floor.
+ This code released into the public domain
+ the*butler
+ Austin, TX
+ October 2008
*/
/*
Headers
+ Only include those headers needed to run the code
*/
#include <stdlib.h> // rand
#include <malloc.h> // malloc
#include <time.h> // time in the random function
#include <newton/newton.h> // NPE header
#include <newton/dMatrix.h> // Matrix stuff
#include <gl/glut.h> // GLUT header
/*
Macros
+ Define some macros to simply our code
*/
#define frand() ((float) rand() / (RAND_MAX+1.0)) //random number between 0 and 1
#define NUMSPHERES 500 // Number of spheres
#define GRAVITY -9.81 // Let's assume we're on earth.
/*
Globals
+ These variables will be called throughout the code
*/
static NewtonWorld* nWorld;
static NewtonBody* sphBody[NUMSPHERES];
static NewtonBody* floorBody;
float fps = 33; // frames per second
dFloat timeStep = 1./fps; // NPE Time step
dFloat width = 2; // Floor dimension
dFloat radius = 0.2; // Sphere radii
dFloat mass = 1.0; // Sphere mass
/*
Called by GLUT when the user resizes the display window
*/
void reshape(int w, int h)
{
if(h == 0)
{
h = 1;
}
float ratio = 1.0f * w / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45,ratio,0.1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 10*width, width, 0, 0, 0, 0 ,1 ,0);
}
/*
GLUT display function
*/
void display()
{
int i;
dMatrix location;
GLfloat mat_red_diffuse[] = { 0.7, 0.0, 0.1, 1.0 };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_red_diffuse);
for (i=0;i<NUMSPHERES;i++)
{
glPushMatrix();
NewtonBodyGetMatrix(sphBody[i], &location[0][0]);
glMultMatrix(&location[0][0]);
glutSolidSphere(radius,20,20);
glPopMatrix();
}
glutSwapBuffers();
}
/*
Called by GLUT to handle to ESC key press
*/
void keyboard(unsigned char key, int x, int y) {
if (key == 27)
{
exit(0);
}
}
/*
Called by GLUT every time step
+ Updates the Newton world
+ Calls GLUT display
*/
void timer(int val)
{
NewtonUpdate(nWorld, timeStep);
glutPostRedisplay();
glutTimerFunc(fps,timer,0);
}
/*
Initialise GLUT settings
*/
void initGL()
{
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 100.0 };
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(0,timer,0);
glutSetCursor(GLUT_CURSOR_NONE);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
}
/*
Memory allocation for Newton
*/
void* PhysicsAlloc (int sizeInBytes)
{
return malloc (sizeInBytes);
}
/*
Memory de-allocation for Newton
*/
void PhysicsFree (void *ptr, int sizeInBytes)
{
free (ptr);
}
/*
Clean up after Newton when app exits
*/
void CleanUp ()
{
NewtonDestroy (nWorld);
}
/*
Newton callback to reset forces every time step
*/
void PhysicsApplyForceAndTorque (const NewtonBody* body)
{
dFloat mass,Ixx,Iyy,Izz;
NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
dVector force (0.0f, mass * GRAVITY, 0.0f);
NewtonBodySetForce (body, &force.m_x);
}
/*
Initialise the Newton Physics Engine
*/
void initNewton()
{
int i;
dFloat x,y=0,z;
dFloat I = (2.0 / 5.0) * mass * radius * radius; //sphere moment of inertia
dVector force (0.0f, mass * GRAVITY, 0.0f); // initial force on spheres is gravity
dMatrix location;
NewtonCollision* collision;
nWorld = NewtonCreate (PhysicsAlloc, PhysicsFree);
atexit(CleanUp);
/////////////////////////////////////////////////////
// create the floor
dVector size (200.0f, 2.0f, 200.0f);
location = GetIdentityMatrix();
location.m_posit.m_y = -1.0f;
collision = NewtonCreateBox (nWorld, size.m_x, size.m_y, size.m_z, NULL);
floorBody = NewtonCreateBody (nWorld, collision);
NewtonBodySetMatrix (floorBody, &location[0][0]);
/////////////////////////////////////////////////////
// create the spheres
// each Newton body must be defined individually
for (i = 0;i<NUMSPHERES;i++)
{
x=frand()*width;
z=frand()*width;
collision = NewtonCreateSphere (nWorld, radius, radius, radius, NULL);
sphBody[i] = NewtonCreateBody (nWorld, collision);
NewtonBodySetAutoFreeze (sphBody[i], 1);
NewtonBodySetForceAndTorqueCallback (sphBody[i], PhysicsApplyForceAndTorque);
NewtonBodySetMassMatrix (sphBody[i], mass, I, I, I);
NewtonBodySetForce (sphBody[i], &force.m_x);
location = GetIdentityMatrix();
location.m_posit.m_x = 0.0+x;
location.m_posit.m_y = 0.1+y;
location.m_posit.m_z = 0.0+z;
NewtonBodySetMatrix (sphBody[i], &location[0][0]);
y=y+2*radius; // let's put each sphere above the other
// beware of going outside of the world dimensions !
}
NewtonReleaseCollision (nWorld, collision);
}
/*
Main
*/
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(0,0);
glutInitWindowSize(640,480);
glutCreateWindow("NPE Hello World Tutorial");
srand(time(NULL));
initNewton();
initGL();
glutMainLoop();
return 0;
}
Users browsing this forum: No registered users and 7 guests