Simple app using GLUT

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Simple app using GLUT

Postby freevryheid » Sat Oct 25, 2008 9:26 pm

Here's some c source code showing the Newton physics engine in action.
freevryheid
 
Posts: 7
Joined: Sat Oct 25, 2008 9:22 pm

Re: Simple app using GLUT

Postby Julio Jerez » Sun Oct 26, 2008 10:56 am

wow that app is very small , and really good for a tutorial.
Thanks
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Simple app using GLUT

Postby freevryheid » Tue Oct 28, 2008 11:28 pm

Simpler still.
Code: Select all
/*
   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;
}

freevryheid
 
Posts: 7
Joined: Sat Oct 25, 2008 9:22 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 15 guests