By the way, let's leave the Clackers project for a moment.
We then tried to create a simple Door to understand Hinge Joint better. Since we still don't know how to use mousepick, we tried to make the door open with a ball falling on it (we set gravity on Z axis to make the ball move toward the door), but even in this case, the hinge moves like it shouldn't: when hit, the door rotates along the Y axes BUT it also rotates a bit around other axis! Then the question is WHY? What did we miss? A door should be very simple to create using Hinge Joints...
We used Newton 2.24 and Irrlicht 1.7.1...
Here is the code of the door project, and the full project with compiled exe in a rar. Please help!
http://www.mediafire.com/?m4v3hvaigsd6y0b
- Code: Select all
#include <Irrlicht.h>
#include <newton.h>
#include <iostream>
#include <windows.h>
//Dichiarazione dei namespaces
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")
//Dichiarazione degli oggetti della classe Irrlicht
//Dichiarazione degli oggetti principali della scena
IVideoDriver* driver = 0;
IrrlichtDevice *device = 0;
ISceneManager* smgr = 0;
ISceneNode* door = 0;
ISceneNode* palla = 0;
ICameraSceneNode* cam_FPS=0;
static NewtonWorld* nWorld;
//Dichiarazione dei corpi rigidi
static NewtonBody* bodyDoor;
static NewtonBody* NPalla;
unsigned int lasttick;
void PhysicsApplyForceAndTorque (const NewtonBody* body, const float timeStep, int threadIndex)
{
float Ixx;
float Iyy;
float Izz;
float mass;
NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz); //Lettura dei membri privati dell'oggetto rigid body
dFloat forcePtr[3] ={ 0, 0, 981.f * mass}; //Definizione delle forze agenti
NewtonBodySetForce(body, &forcePtr[0]); //Applicazione delle forze
}
void InitScene() //Inizializzazione della scena
{
//Creazione del device video
device = createDevice(EDT_OPENGL, //tipo
dimension2d<u32>(800,600), //dimensione
32, //profondit‡
false, //fullscreen
true, //stencyl buffer
false //vsync
);
driver = device->getVideoDriver();
//Setting delle proprietà dello scene manager e del device
smgr = device->getSceneManager();
smgr->setShadowColor(video::SColor(150,0,0,0));
device->getCursorControl()->setVisible(false);
smgr->addLightSceneNode(0, //parent
core::vector3df(-500,500,-500), //posizione
video::SColorf(1.0f, 1.0f, 1.0f, 1.0f),//color
400.0f //raggio
);
smgr->addLightSceneNode(0, //parent
core::vector3df(0,500,-500), //posizione
video::SColorf(1.0f, 1.f, 1.f, 1.0f), //color
600.0f //raggio
);
//Creazione del piano
door = smgr->addCubeSceneNode(1);
door->setMaterialTexture(0, driver->getTexture("chess.jpg"));
door->setScale(core::vector3df(100,300,20));
door->setMaterialFlag(EMF_LIGHTING, true);
door->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
//Creazione dello sfondo
smgr->addSkyBoxSceneNode(driver->getTexture("starry.jpg"),
driver->getTexture("starry.jpg"),
driver->getTexture("starry.jpg"),
driver->getTexture("starry.jpg"),
driver->getTexture("starry.jpg"),
driver->getTexture("starry.jpg")
);
//Creazione del mondo di newton
nWorld = NewtonCreate();
//Definizione delle grandezze che governano l'urto tra oggetti del gruppo i
int i = NewtonMaterialGetDefaultGroupID(nWorld);
NewtonMaterialSetDefaultFriction(nWorld, i, i, .4f, .2f);
NewtonMaterialSetDefaultElasticity(nWorld, i, i, 1);
float minPtr[3] = {-10000.f,-10000.f,-10000.f};
float maxPtr[3] = {10000.f,10000.f,10000.f};
NewtonSetWorldSize(nWorld, &minPtr[0], &maxPtr[0]);
//Collisioni
NewtonCollision *collisionDoor;
collisionDoor = NewtonCreateBox(nWorld, 100, 300, 20, -1, NULL);
//Corpi rigidi
bodyDoor = NewtonCreateBody (nWorld, collisionDoor);
//Una volta associata la collisione può essere distrutta per liberare memoria
NewtonReleaseCollision (nWorld, collisionDoor);
//Associazione delle proprietà fisiche ai corpi rigidi
NewtonBodySetMassMatrix(bodyDoor, 100.0f, 1.0f, 1.0f, 1.0f);
//Setting iniziali dei corpi rigidi
matrix4 matBallPos;
matBallPos.setTranslation(vector3df(0,0,0));
NewtonBodySetMatrix(bodyDoor, matBallPos.pointer());
//NewtonBodySetForceAndTorqueCallback (bodyDoor, PhysicsApplyForceAndTorque);
palla = smgr->addSphereSceneNode(20);
palla->setPosition(core::vector3df(20,0,-100));
palla->setMaterialTexture(0,driver->getTexture("cemento.jpg"));
palla->setMaterialFlag(EMF_LIGHTING,false);
palla->setMaterialFlag(EMF_NORMALIZE_NORMALS,true);
NewtonCollision * NPallaColl=NewtonCreateSphere(nWorld,20,20,20,1,NULL);
NPalla=NewtonCreateBody(nWorld,NPallaColl);
matrix4 objM;
objM.makeIdentity();
objM.setTranslation(vector3df(20,0,-100));
NewtonBodySetMatrix(NPalla,objM.pointer());
NewtonBodySetMassMatrix(NPalla, 100.0f, 1.0f, 1.0f, 1.0f);
float pivot[3];
float pindir[3];
/*pivot[0] = -50;
pivot[1] = -100;
pivot[2] = 0;
pindir[0] = 0;
pindir[1] = 1;
pindir[2] = 0;
NewtonJoint* joinBall=NewtonConstraintCreateHinge(nWorld, pivot, pindir, bodyDoor, NULL);
NewtonJointSetStiffness(joinBall, 1.0f);
pivot[0] = -50;
pivot[1] = -50;
pivot[2] = 0;
pindir[0] = 0;
pindir[1] = 1;
pindir[2] = 0;
NewtonJoint* joinBall2=NewtonConstraintCreateHinge(nWorld, pivot, pindir, bodyDoor, NULL);
NewtonJointSetStiffness(joinBall2, 1.0f);*/
pivot[0] = -50;
pivot[1] = 0;
pivot[2] = 0;
pindir[0] = 0;
pindir[1] = 1;
pindir[2] = 0;
NewtonJoint* joinBall3=NewtonConstraintCreateHinge(nWorld, pivot, pindir, bodyDoor, NULL);
NewtonJointSetStiffness(joinBall3, 1.0f);
/*pivot[0] = -50;
pivot[1] = 50;
pivot[2] = 0;
pindir[0] = 0;
pindir[1] = 1;
pindir[2] = 0;
NewtonJoint* joinBall4=NewtonConstraintCreateHinge(nWorld, pivot, pindir, bodyDoor, NULL);
NewtonJointSetStiffness(joinBall4, 1.0f);
pivot[0] = -50;
pivot[1] = 100;
pivot[2] = 0;
pindir[0] = 0;
pindir[1] = 1;
pindir[2] = 0;
NewtonJoint* joinBall5=NewtonConstraintCreateHinge(nWorld, pivot, pindir, bodyDoor, NULL);
NewtonJointSetStiffness(joinBall5, 1.0f);*/
NewtonBodySetForceAndTorqueCallback (NPalla, PhysicsApplyForceAndTorque);
//Inizializzazione delle telecamere
cam_FPS = smgr->addCameraSceneNodeFPS();
cam_FPS->setPosition(core::vector3df(0,0,-300));
smgr->setActiveCamera(cam_FPS);
}
void DrawScene() //Disegna la scena ad ogni step
{
if (device->getTimer()->getTime() > lasttick + 10) { //Controllo dell'avanzamento
lasttick = device->getTimer()->getTime();
NewtonUpdate(nWorld, 0.01f);
float matrixDoor[4][4];
NewtonBodyGetMatrix(bodyDoor, &matrixDoor[0][0]); //Acquisizione delle nuove coordinate dell'oggetto corpo rigido
matrix4 matDoor;
memcpy(matDoor.pointer(), matrixDoor, sizeof(float)*16);
door->setPosition(matDoor.getTranslation());
door->setRotation(matDoor.getRotationDegrees()); //Setting dei nuovi orientamento e posizione dell'oggetto
float matrixBall[4][4];
NewtonBodyGetMatrix(NPalla, &matrixBall[0][0]); //Acquisizione delle nuove coordinate dell'oggetto corpo rigido
matrix4 matBall;
memcpy(matBall.pointer(), matrixBall, sizeof(float)*16);
palla->setPosition(matBall.getTranslation());
palla->setRotation(matBall.getRotationDegrees());
}
}
int main()
{
//Inizializzazione della scena
InitScene();
while(device->run()) //While di visualizzazione
{
DrawScene();
driver->beginScene(true, true, video::SColor(0,0,0,0));
smgr->drawAll();
driver->endScene();
}
NewtonDestroy(nWorld); //Distruzione del mondo newton
device->drop(); //Distruzione della scena
return 0;
}
EDIT: oh I forgot one thing: we tried to put 5 Hinge Joints on the side of the door (now commented lines in the file) and it behaves much more like we would like... Still don't understand why: evene a single Hinge should work, since it should have an "infinite" axis...
