Newton physics help (objects goes through each others)

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
rrg
Posts: 41
Joined: Sun Nov 04, 2007 6:22 pm

Newton physics help (objects goes through each others)

Post by rrg »

I'm starting a new project and i decided to add physics to it. I choose Newton Game Dynamics engine. So I looked at tutorials and coded a ball that falls and a block that just sits there in space because there is no floor. The ball falls straight though the block as if it wasn't there. I tried and i ran out of ideas I just can't make the ball bounce of the block. here is my code and i hope someone could help me with it. thanks.


Code: Select all

#include <Irrlicht.h>
#include <Newton.h>

#pragma comment(lib, "Irrlicht.lib")
#pragma comment(lib, "Newton.lib")

using namespace irr;
using namespace video;
using namespace core;
using namespace scene;

static NewtonWorld* nWorld;
static NewtonCollision *collision;
static NewtonBody* body1;
static NewtonBody* body2;

static IVideoDriver* driver;
static IrrlichtDevice* device;
static ISceneManager* smgr;


static ISceneNode* sphereNode;
static ISceneNode* cubeNode;
static ICameraSceneNode* cam;
unsigned int clock;

static void  PhysicsApplyForceAndTorque (const NewtonBody* body);
static void  PhysicsBodyDestructor (const NewtonBody* body);

static void IntitScene()
{
	device = createDevice(EDT_DIRECT3D9,dimension2d<s32>(640,480),32,false,false,false);
	driver = device->getVideoDriver();
	 smgr = device->getSceneManager();
	
	 // simple camera
	cam = smgr->addCameraSceneNode(0,vector3df(0,0,-50),vector3df(0,0,0),-1);

	// physics begins
	 nWorld = NewtonCreate (NULL,NULL);
	


	  // create sphere
	 collision = NewtonCreateSphere (nWorld, 5, 5, 5, NULL); 

	 sphereNode = smgr->addSphereSceneNode(5);
	 sphereNode->setMaterialTexture(0,driver->getTexture("../data/box.jpg"));
	 sphereNode->setMaterialFlag(EMF_LIGHTING,false);

	 body1 = NewtonCreateBody(nWorld,collision);
	 NewtonBodySetUserData (body1,sphereNode);
	 
	 NewtonBodySetForceAndTorqueCallback (body1, PhysicsApplyForceAndTorque);
	 NewtonBodySetMassMatrix (body1, 1.0f, 1.0f, 1.0f, 1.0f);

	matrix4 mat;
	mat.setTranslation(vector3df(0,15,0));
	NewtonBodySetMatrix(body1, mat.pointer());
	NewtonReleaseCollision (nWorld, collision);

	






		//create box
	 collision = NewtonCreateBox(nWorld, 5, 5, 5, NULL); 

	 cubeNode = smgr->addCubeSceneNode(10);
	 cubeNode->setMaterialTexture(0,driver->getTexture("../data/crate.jpg"));
	 cubeNode->setMaterialFlag(EMF_LIGHTING,false);
	
	 body2 = NewtonCreateBody(nWorld,collision);
	 NewtonBodySetUserData (body2,cubeNode);
	 
	 NewtonBodySetForceAndTorqueCallback (body2, PhysicsApplyForceAndTorque);
	 NewtonBodySetMassMatrix (body2, 1.0f, 1.0f, 1.0f, 1.0f);

	matrix4 mat1;
	mat1.setTranslation(vector3df(0,30,20));
	NewtonBodySetMatrix(body2, mat1.pointer());
	NewtonReleaseCollision (nWorld, collision);
	

}

void PhysicsApplyForceAndTorque (const NewtonBody* body)
{
   float mass;
  
   vector3df force (0.0f, -mass * 9.8f , 0.0f);
   vector3df torque (0.0f, 0.0f, 0.0f);

   NewtonBodySetForce(body, &force.X);
} 
void DrawScene()
{
	if (device->getTimer()->getTime() > clock + 10) 
	{	
		clock = device->getTimer()->getTime();
		NewtonUpdate(nWorld, 0.01f);
	}
	  float matrix[4][4];
        NewtonBodyGetMatrix(body1, &matrix[0][0]);
		

	matrix4 mat;
	memcpy(mat.pointer(), matrix, sizeof(float)*16);

	 sphereNode->setPosition(mat.getTranslation());
    sphereNode->setRotation(mat.getRotationDegrees());



}

int main()
{
   
  IntitScene();
   
   while(device->run())
   {
      DrawScene();

      driver->beginScene(true, true, video::SColor(0,0,0,0));

      smgr->drawAll();

      driver->endScene();

   }
   NewtonDestroy(nWorld);

   device->drop();

   return 0;
}
Yustme
Posts: 107
Joined: Sat Dec 01, 2007 10:50 pm

Post by Yustme »

Hi,

You need a callback function to check for collisions.

Put this line above your main() function:

Code: Select all

static void PhysicsSetTransform(const NewtonBody* body);

When you create the scene nodes, you need to register the callback function for that scene node like you did for the NewtonBodyDestructor like this:

Code: Select all

NewtonBodySetForceAndTorqueCallback(body, PhysicsApplyForceAndTorque);

The body of the callback should look like this (which you have in DrawScene()):

Code: Select all

static void PhysicsSetTransform(const NewtonBody* body)
{
	matrix4 mat;
	memcpy(mat.pointer(), matrix, sizeof(float) * 16);
	
	ISceneNode* node = (ISceneNode*)NewtonBodyGetUserData(body);
	
	if(node)
	{
		node->setPosition(mat.getTranslation());		
		node->setRotation(mat.getRotationDegrees());
	}
}

The callback function gets called immediately when 2 bodies get close to each other and about to collide.

Calling the DrawScene function in your while loop wont check the 2 bodies for collision in time.

So the DrawScene() function will either be too early or too late to check for collisions and then the bodies go through each other.

Let me know if that helped.
Post Reply