I am trying to integrate Newton in my Irrlicht project so I was trying to reproduce an example very similar to mercior's tutorial. I perfectly know that mercior tutorial is old and so I tried to modify my example code with code snippets found here on this forum but I still can't get my newton code to work. I need help! This is my code, very simple test application like in mercior tutorial. Loads a bsp level and throws boxes with left mouse button. The problem is that when I thow boxes they don't move! Boxes are frozen in middle-air or even through walls:
Code: Select all
#include <irrlicht.h>
#include <Newton.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
static NewtonWorld* nWorld;
IrrlichtDevice *device = NULL;
IVideoDriver* driver = NULL;
ISceneManager* smgr = NULL;
float NewtonToIrr = 32.0f;
float IrrToNewton = 1/NewtonToIrr;
IGUIEnvironment *guienv = NULL;
ICameraSceneNode *cam = NULL;
struct NewtonCube {
IAnimatedMesh *mesh;
ISceneNode *node;
NewtonBody *body;
const NewtonBody *waterBody;
};
NewtonCube *cubes[512];
int currentCube = 0;
// allocation of memory from Newton
void* _cdecl NewtonAlloc (int sizeInBytes) {
return new char[sizeInBytes];
}
// destruction of memory from Newton
void _cdecl NewtonFree (void *ptr, int sizeInBytes) {
char *tmp;
tmp = (char*) ptr;
delete[] tmp;
}
/*
Function: AddGlobalForce (vector3df Force, vector3df Point, matrix4 BodyMatrix,const NewtonBody* body)
Returns: Nothing
Parameters: vector3df Force -- the force you want to apply
vector3df Point -- global space location to apply the force
matrix4 BodyMatrix -- Newton Matrix describing object
NewtonBody* body -- the body in question
Purpose: Add a force to an object displaced from the center of mass
Note: Because of the displacement, you will get a spin or torque, and
you have to tell Newton what that spin is. Thats what this function
does.
*/
void AddGlobalForce (vector3df Force, vector3df Point, matrix4 BodyMatrix,const NewtonBody* body)
{
vector3df R = Point - BodyMatrix.getTranslation();
vector3df Torque = R.crossProduct(Force);
NewtonBodyAddForce (body,&Force.X);
NewtonBodyAddTorque (body,&Torque.X);
}
/*
Function: AddLocalForce (vector3df Force, vector3df LocalPoint, matrix4 BodyMatrix,const NewtonBody* body)
Returns: Nothing
Parameters: vector3df Force -- the force you want to apply, in local space
vector3df Point -- local space location to apply the force
matrix4 BodyMatrix -- Newton Matrix describing object
NewtonBody* body -- the body in question
Purpose: Takes a local force and displacement and translates it into a global
force request
Note: Because of the displacement, you will get a spin or torque, and
you have to tell Newton what that spin is. Thats what this function
does.Called only from within ApplyTorqueandForceHandler
*/
void AddLocalForce (vector3df LocalForce, vector3df LocalPoint, matrix4 BodyMatrix,const NewtonBody* body)
{
vector3df GlobalForce,GlobalPoint;
BodyMatrix.transformVect(LocalForce,GlobalForce);
BodyMatrix.transformVect(LocalPoint,GlobalPoint);
if (LocalForce.X == 0.0f && LocalForce.Y == 0.0f && LocalForce.Z == 0.0f)
{
}
else
{
AddGlobalForce (GlobalForce, GlobalPoint,BodyMatrix,body);
}
}
void _cdecl NewtonDebugCollision(const NewtonBody* body, int vertexCount, const float* FaceArray, int faceId)
{
core::vector3df p0 (FaceArray[0], FaceArray[1], FaceArray[2] );
const video::SColor c0(255,55,255,0);
for (int i = 2; i < vertexCount; i ++)
{
core::vector3df p1( FaceArray[(i-1) * 3 + 0], FaceArray[(i-1) * 3 + 1], FaceArray[(i-1) * 3 + 2] );
core::vector3df p2( FaceArray[i * 3 + 0], FaceArray[i * 3 + 1], FaceArray[i * 3 + 2] );
core::triangle3df t;
t.set(p1*NewtonToIrr,
p2*NewtonToIrr,
p0*NewtonToIrr);
driver->draw3DTriangle(t, c0);
}
}
void _cdecl NewtonDebugBody (const NewtonBody* body) {
matrix4 mat;
SMaterial material;
material.Texture1 = 0;
material.Lighting = false;
driver->setTransform(video::ETS_WORLD, mat);
driver->setMaterial(material);
NewtonBodyForEachPolygonDo(body,NewtonDebugCollision);
}
static void setTransform(const NewtonBody* body, const float* matrix) {
//get graphic object
ISceneNode* node = (ISceneNode*) NewtonBodyGetUserData(body);
//copy matrix to an irrlicht matrix
matrix4 mat;
memcpy(mat.M, matrix, sizeof(float)*16);
//set transformation
node->setPosition(mat.getTranslation() * NewtonToIrr);
node->setRotation(mat.getRotationDegrees());
}
static void setForceAndTorque(const NewtonBody* body) {
float mass;
float Ixx;
float Iyy;
float Izz;
matrix4 mat;
mat.makeIdentity();
NewtonBodyGetMatrix(body,mat.M);
NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
vector3df force(0, -mass* 9.8f, 0.0);
vector3df torque(0, 00.0f, 0);
vector3df mforce(0,0,5);
vector3df displace(2,0,0);
NewtonBodyAddForce(body, &force.X);
AddLocalForce(mforce,displace,mat,body);
}
class MyEventReceiver : public IEventReceiver {
public:
virtual bool OnEvent(SEvent event) {
if (event.EventType == irr::EET_MOUSE_INPUT_EVENT && event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
/* make a cube where the camera is and set its velocity to follow the target */
vector3df camvec = (cam->getTarget() - cam->getPosition()).normalize() * 500;
NewtonCube *tmp = new NewtonCube;
tmp->mesh = smgr->getMesh("media/smallcube.3ds");
tmp->node = smgr->addAnimatedMeshSceneNode(tmp->mesh);
tmp->node->setMaterialTexture(0, driver->getTexture("media/crate.jpg"));
tmp->node->setMaterialFlag(EMF_LIGHTING, false);
tmp->waterBody = NULL;
/* Create a box primitive. 38 is just an estimated value of the size of the model */
float x = 40 * IrrToNewton;
float y = 40 * IrrToNewton;
float z = 40 * IrrToNewton;
NewtonCollision* collision;
collision = NewtonCreateBox(nWorld, x, y, z, NULL);
// creatye the body
NewtonBody* body;
body = NewtonCreateBody(nWorld, collision);
tmp->body = body;
// the box is metal
//NewtonBodySetMaterialGroupID (body, m_metalMaterial);
/* release the collsion tree (this way the application does not have to do book keeping of Newton objects */
NewtonReleaseCollision (nWorld, collision);
// Set user data pointer to the scene node
NewtonBodySetUserData(body, tmp);
// Set body mass & inertia matrix
float mass = 10.0f;
float Ixx = 0.7f * mass * (y * y + z * z) / 12.0f;
float Iyy = 0.7f * mass * (x * x + z * z) / 12.0f;
float Izz = 0.7f * mass * (x * x + y * y) / 12.0f;
NewtonBodySetMassMatrix (body, mass, Ixx, Iyy, Izz);
// leave the sleep tolerance alone
NewtonBodySetFreezeTreshold(body, 1.0, 1.0, 1);
// Set callback functions for the body
NewtonBodySetTransformCallback(body, setTransform);
NewtonBodySetForceAndTorqueCallback(body, setForceAndTorque);
// Set the position of the body
matrix4 mat;
mat.setTranslation(cam->getPosition() * IrrToNewton);
NewtonBodySetMatrix(body, &mat.M[0]);
tmp->node->setPosition(cam->getPosition());
setTransform(body, &mat.M[0]);
vector3df nVeloc (camvec * IrrToNewton);
NewtonBodySetVelocity(body, &nVeloc.X);
cubes[currentCube] = tmp;
currentCube ++;
}
return false;
}
};
MyEventReceiver receiver;
int main() {
device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(800, 600), 16, false, false, false, &receiver);
device->setWindowCaption(L"Newton and Irrlicht Engine Demo");
driver = device->getVideoDriver();
smgr = device->getSceneManager();
guienv = device->getGUIEnvironment();
/** NEWTON INITIALIZATION **/
nWorld = NewtonCreate(NewtonAlloc, NewtonFree);
// Set up default material properties for newton
int i = NewtonMaterialGetDefaultGroupID(nWorld);
NewtonMaterialSetDefaultFriction (nWorld, i, i, 0.8f, 0.4f);
NewtonMaterialSetDefaultElasticity (nWorld, i, i, 0.3f);
NewtonMaterialSetDefaultSoftness (nWorld, i, i, 0.05f);
NewtonMaterialSetCollisionCallback (nWorld, i, i, NULL, NULL, NULL, NULL);
/** BSP LOADING IN NEWTON **/
//Level
device->getFileSystem()->addZipFileArchive("media/map-20kdm2.pk3");
scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");
scene::ISceneNode* q3node = 0;
if (q3levelmesh)
q3node = smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0));
q3node->setPosition(core::vector3df(-1370,-130,-1400));
//LevelNewtonCollision
NewtonCollision* nmapcollision = NewtonCreateTreeCollision(nWorld, NULL);
NewtonTreeCollisionBeginBuild(nmapcollision);
int cMeshBuffer, j;
int v1i, v2i, v3i;
IMeshBuffer *mb;
float vArray[9]; // vertex array (3*3 floats)
int tmpCount = 0;
core::aabbox3d<f32> box;
//size the box in Newton units
box = q3levelmesh->getMesh(0)->getBoundingBox();
vector3df size = box.getExtent()*IrrToNewton;
for (cMeshBuffer=0; cMeshBuffer<q3levelmesh->getMesh(0)->getMeshBufferCount(); cMeshBuffer++)
{
mb = q3levelmesh->getMesh(0)->getMeshBuffer(cMeshBuffer);
S3DVertex2TCoords* mb_vertices = (S3DVertex2TCoords*)mb->getVertices();
u16* mb_indices = mb->getIndices();
// add each triangle from the mesh
for (j=0; j<mb->getIndexCount(); j+=3)
{
// printf("buff %d count %d\n",cMeshBuffer,j);
v1i = mb_indices[j];
v2i = mb_indices[j+1];
v3i = mb_indices[j+2];
vArray[0] = mb_vertices[v1i].Pos.X* IrrToNewton;
vArray[1] = mb_vertices[v1i].Pos.Y* IrrToNewton;
vArray[2] = mb_vertices[v1i].Pos.Z* IrrToNewton;
vArray[3] = mb_vertices[v2i].Pos.X* IrrToNewton;
vArray[4] = mb_vertices[v2i].Pos.Y* IrrToNewton;
vArray[5] = mb_vertices[v2i].Pos.Z* IrrToNewton;
vArray[6] = mb_vertices[v3i].Pos.X* IrrToNewton;
vArray[7] = mb_vertices[v3i].Pos.Y* IrrToNewton;
vArray[8] = mb_vertices[v3i].Pos.Z* IrrToNewton;
NewtonTreeCollisionAddFace(nmapcollision, 3, &vArray[0], 12, 1);
}
}
NewtonTreeCollisionEndBuild(nmapcollision, 0);
NewtonBody* nmapbody = NewtonCreateBody(nWorld, nmapcollision);
// set the newton world size based on the bsp size
float boxP0[3];
float boxP1[3];
float matrix[4][4];
matrix4 mmm;
mmm.setTranslation(vector3df(-1370,-130,-1400)*IrrToNewton);
NewtonBodySetMatrix(nmapbody,&mmm.M[0]);
NewtonCollisionCalculateAABB (nmapcollision, &matrix[0][0], &boxP0[0], &boxP1[0]);
NewtonSetWorldSize (nWorld, (float*)boxP0, (float*)boxP1);
device->getCursorControl()->setVisible(false);
cam = smgr->addCameraSceneNodeFPS();
cam->setPosition(vector3df(0.0, 100.0, 150.0));
while(device->run()) {
NewtonUpdate(nWorld, 0.01f);
driver->beginScene(true, true, SColor(0,200,200,200));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
device->drop();
NewtonDestroy(nWorld);
return 0;
}
Please help me
[/code]