Node not matching Newton collision object ( FIXED(kind of) )
Posted: Mon Aug 07, 2006 12:30 am
Hi, I found this code here ]http://irrlicht.sourceforge.net/phpBB2/ ... whatsoever and I thought i'd try it out as I assumed it was "working" because i was having trouble with all other samples etc for Newton but the problem I have is that the mesh is way up in the air, but the debugging shape for Newton is on the ground. The translation, force and torque callbacks are never being called. So I was wondering if anyone had experienced problems with this and if so how they fixed it.
Thanks in advance.
[/url]
Oh and its the latest version of Irrlicht and Newton that i'm using (1.0 and 1.53 respectively)
Thanks in advance.
Code: Select all
#include <Irrlicht.h>
#include "newton.h"
#include <memory.h>
static NewtonWorld* nWorld;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(lib, "Newton.lib")
IrrlichtDevice *device = NULL;
IVideoDriver* driver = NULL;
ISceneManager* smgr = NULL;
float NewtonToIrr = 32.0f;
float IrrToNewton = 1/NewtonToIrr;
IGUIStaticText* pText = NULL;
bool debugOn = true;
class MyEventReceiver : public IEventReceiver
{
public:
///////////////////////////
virtual bool OnEvent(SEvent event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT&&
event.KeyInput.PressedDown)
{
switch(event.KeyInput.Key)
{
case KEY_ESCAPE:
device->closeDevice();
break;
case KEY_KEY_D:
debugOn = !debugOn;
break;
}
}// pressdown
return 0;
}
};
MyEventReceiver receiver;
// 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);
}
int main()
{
device = createDevice(EDT_DIRECT3D9,
dimension2d<s32>(640,480), 32,false,false,false,&receiver);
driver = device->getVideoDriver();
smgr = device->getSceneManager();
IGUIEnvironment* env = device->getGUIEnvironment();
pText = env->addStaticText(L"fred",core::rect<int>(20,20,440,200), false);
pText->setOverrideColor(video::SColor(255,240,240,235));
pText->setOverrideFont(
env->getFont("midfont.bmp"));
//1. Create Newtonworld
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);
//MESH
//ISceneNode* node = smgr->addTestSceneNode();
core::aabbox3d<f32> sbox;
vector3df ssize;
float sss = 2.0f;
IAnimatedMesh* mesh = smgr->getMesh("sydney.md2");
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
if (node)
{
node->setMaterialFlag(EMF_LIGHTING, false);
node->setFrameLoop(320, 368);
node->setScale(vector3df(sss,sss,sss));
node->setMaterialTexture( 0, driver->getTexture("sydney.bmp") );
node->setPosition(core::vector3df(0,530,30));
node->setAnimationSpeed(50);
//size the box in Newton units
sbox = mesh->getMesh(0)->getBoundingBox();
ssize = sbox.getExtent()*IrrToNewton*sss;
}
//2.a Define Newtoncollision
NewtonCollision* myShape = NewtonCreateSphere(nWorld, ssize.X/2, ssize.Y/2, ssize.Z/2, NULL);
//b. Create NewtonBody
NewtonBody* myBody = NewtonCreateBody(nWorld, myShape);
//c. Set Body Properties
NewtonBodySetMassMatrix(myBody, 1.0f, 1.0f, 1.0f, 1.0f);
NewtonBodySetForceAndTorqueCallback(myBody, setForceAndTorque);
NewtonBodySetUserData(myBody, (void*) node); //with this you are sending your graphic pointer to Newton.
NewtonBodySetTransformCallback(myBody, setTransform);
NewtonBodySetLinearDamping(myBody,1);
vector3df rd(1,1,1);
NewtonBodySetAngularDamping(myBody,&rd.X);
NewtonJoint* upVector;
vector3df upDirection (0.0f, 1.0f, 0.0f);
upVector = NewtonConstraintCreateUpVector (nWorld, &upDirection.X, myBody);
ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 200.0f, 250.0f);
camera->setPosition(vector3df(0,10,-120));
camera->setTarget(vector3df(0,0,0));
//Level
device->getFileSystem()->addZipFileArchive
("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);
int rate;
wchar_t tmp[1024];
while(device->run())
{
NewtonUpdate(nWorld, 0.01f);
//camera->setTarget(node->getPosition());
driver->beginScene(true, true, video::SColor(0,0,0,0));
if (debugOn)
{
NewtonWorldForEachBodyDo (nWorld, NewtonDebugBody);
}
rate = driver->getFPS();
vector3df cPos = camera->getAbsolutePosition();
swprintf(tmp, 1024, L"camera[%2.1f,%2.1f,%2.1f] fps %d\nD toggle Debug",cPos.X,cPos.Y,cPos.Z,rate);
pText->setText(tmp);
smgr->drawAll();
env->drawAll();
driver->endScene();
}
device->drop();
// 4. Destroy World
NewtonDestroy(nWorld);
return 0;
}
Oh and its the latest version of Irrlicht and Newton that i'm using (1.0 and 1.53 respectively)