Which is "easier" to integrate and use, ODE, Tokam
Which is "easier" to integrate and use, ODE, Tokam
I was curious, which of the 3 was actualy the easist to integrate for my use? I am looking at doing some "minor" physics and colllision detection response. I am looking for open platform, as well as simple to use. Which one do you all recomend?
I haven't tried ODE.
I just took Couch's Tokamak tutorial and got it running/figured out and replaced all the special block creation in less than 1/2 an hour. Now I'm making pong with it to see if it is really as easy at it seems.
This is my changes, all I really did was remove the custom scenenodes and used the irrlicht ones.
I just took Couch's Tokamak tutorial and got it running/figured out and replaced all the special block creation in less than 1/2 an hour. Now I'm making pong with it to see if it is really as easy at it seems.
This is my changes, all I really did was remove the custom scenenodes and used the irrlicht ones.
Code: Select all
#include <irrlicht.h>
#include <tokamak.h>
#include <windows.h>
#include <time.h>
#pragma comment(lib, "Irrlicht.lib")
#ifdef _DEBUG
#pragma comment(lib, "tokamak_d.lib")
#else
#pragma comment(lib, "tokamak.lib")
#endif
#pragma comment(lib, "winmm.lib")
#define PI 3.1415926
#define CUBECOUNT 30
#define CUBEX 5.0
#define CUBEY 5.0
#define CUBEZ 5.0
#define CUBEMASS 50.0f
#define FLOORSIZE 300
irr::scene::ICameraSceneNode* camera = 0;
neSimulator *gSim = NULL;
neRigidBody *gCubes[CUBECOUNT];
neAnimatedBody *gFloor = NULL;
bool gbUseHFTimer;
INT64 gCurrentTime;
float gfTimeScale;
class MyEventReceiver : public irr::IEventReceiver {
public:
virtual bool OnEvent(irr::SEvent event) {
if (camera)
return camera->OnEvent(event);
return false;
}
};
bool InitPhysics(void) {
neGeometry *geom;
neV3 boxSize1;
neV3 gravity;
neV3 pos;
f32 mass;
neSimulatorSizeInfo sizeInfo;
int i;
sizeInfo.rigidBodiesCount = CUBECOUNT;
sizeInfo.animatedBodiesCount = 1;
s32 totalBody = sizeInfo.rigidBodiesCount + sizeInfo.animatedBodiesCount;
sizeInfo.geometriesCount = totalBody;
sizeInfo.overlappedPairsCount = totalBody * (totalBody - 1) / 2;
sizeInfo.rigidParticleCount = 0;
sizeInfo.constraintsCount = 0;
sizeInfo.terrainNodesStartCount = 0;
gravity.Set(0.0f, -10.0f, 0.0f);
gSim = neSimulator::CreateSimulator(sizeInfo, NULL, &gravity);
srand(time(0));
for (i=0; i<CUBECOUNT; i++) {
gCubes[i] = gSim->CreateRigidBody();
geom = gCubes[i]->AddGeometry();
boxSize1.Set(CUBEX, CUBEY, CUBEZ);
geom->SetBoxSize(boxSize1[0], boxSize1[1], boxSize1[2]);
gCubes[i]->UpdateBoundingInfo();
mass = CUBEMASS;
gCubes[i]->SetInertiaTensor(neBoxInertiaTensor(boxSize1[0], boxSize1[1], boxSize1[2], mass));
gCubes[i]->SetMass(mass);
pos.Set((rand()%10) / 20.0f * CUBEX, 4.0f + i * (CUBEY + 1),(rand()%10)/ 20.0f * CUBEZ);
gCubes[i]->SetPos(pos);
}
gFloor = gSim->CreateAnimatedBody();
geom = gFloor->AddGeometry();
boxSize1.Set(FLOORSIZE, 0.0f, FLOORSIZE);
geom->SetBoxSize(boxSize1[0],boxSize1[1],boxSize1[2]);
gFloor->UpdateBoundingInfo();
pos.Set(0.0f, 0.0f, 0.0f);
gFloor->SetPos(pos);
return true;
}
void KillPhysics(void) {
if (gSim) {
neSimulator::DestroySimulator(gSim);
gSim = NULL;
}
}
bool InitTimer(void) {
INT64 TimerFrequency;
if (QueryPerformanceFrequency( (LARGE_INTEGER*)&TimerFrequency)) {
gfTimeScale = 1.0f / TimerFrequency;
QueryPerformanceCounter((LARGE_INTEGER *) &gCurrentTime);
gbUseHFTimer = true;
return true;
} else {
gfTimeScale = 0.001f;
gCurrentTime = timeGetTime();
gbUseHFTimer = false;
return true;
}
return false;
}
float GetElapsedTime() {
INT64 newTime;
float fElapsed;
if (gbUseHFTimer)
QueryPerformanceCounter((LARGE_INTEGER *) &newTime);
else
newTime=timeGetTime();
fElapsed = (float)((newTime - gCurrentTime) * gfTimeScale);
gCurrentTime = newTime;
return fElapsed;
}
int main() {
MyEventReceiver receiver;
float fElapsed;
static float fLastElapsed;
int i;
irr::core::vector3df TempVect;
irr::IrrlichtDevice *device = irr::createDevice(irr::video::EDT_DIRECTX9, irr::core::dimension2d<irr::s32>(640, 480), 16, false, false, &receiver);
irr::video::IVideoDriver* driver = device->getVideoDriver();
irr::scene::ISceneManager* smgr = device->getSceneManager();
camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
camera->setPosition(irr::core::vector3df(20,30,20));
camera->setTarget(irr::core::vector3df(-20,-30,-20));
device->getCursorControl()->setVisible(false);
InitPhysics();
irr::scene::ISceneNode *CubeNode[CUBECOUNT];
for (i=0; i<CUBECOUNT;i++) {
CubeNode[i] = smgr->addTestSceneNode(CUBEX,0,-1);
CubeNode[i]->setMaterialTexture(0,driver->getTexture("ball.bmp"));
}
irr::scene::IAnimatedMeshSceneNode* tempNode = smgr->addAnimatedMeshSceneNode(smgr->addHillPlaneMesh("hill",irr::core::dimension2d<f32>(300,300),irr::core::dimension2d<s32>(1,1)),0,-1,irr::core::vector3df(150,0,150));
InitTimer();
fLastElapsed = 0;
int lastFPS = -1;
while(device->run()) {
fElapsed = GetElapsedTime();
if (fLastElapsed != 0) {
if (fElapsed > fLastElapsed * 1.2f)
fElapsed = fLastElapsed * 1.2f;
if (fElapsed < fLastElapsed * 0.8f)
fElapsed = fLastElapsed * 0.8f;
}
if (fElapsed > 1.0f / 45.0f)
fElapsed = 1.0f / 45.0f;
fLastElapsed = fElapsed;
gSim->Advance(fElapsed);
for (i=0; i<CUBECOUNT; i++) {
neV3 p = gCubes[i]->GetPos();
TempVect.X = p[0];
TempVect.Y = p[1];
TempVect.Z = p[2];
CubeNode[i]->setPosition(TempVect);
neQ q = gCubes[i]->GetRotationQ();
TempVect.Y = q.Y;
TempVect.X = q.X;
TempVect.Z = q.Z;
TempVect *= 180 / PI;
CubeNode[i]->setRotation(TempVect);
}
driver->beginScene(true, true, irr::video::SColor(0,100,100,100));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps) {
wchar_t tmp[1024];
swprintf(tmp, 1024, L"Physics Example- Irrlicht & Tokamak Engines(fps:%d)", fps);
device->setWindowCaption(tmp);
lastFPS = fps;
}
}
KillPhysics();
//for (i=0; i<CUBECOUNT;i++)
// CubeNode[i]->drop();
device->drop();
return 0;
}
Crud, how do I do this again?
I have a lot of experience with ODE and it's pretty easy (I got mine setup in about 2 hours with full collision and everything). I won't comment about the others, but I will say this: you said "Open Platform" -- that rules out newton, and I think also tokamak. So, you're left with ODE if you want open platform.
Good luck man!
Good luck man!
My experience with ODE:
In ODE it is very difficult to adjust the parameters that the behaviour of your simulation is what you would expect.
As example following parameters.
The gravitation. Values of -0.5 are in tutorials used. Setting it to -9.1 often leads to unstable behaviour. But why should g be another value than -9.1 or is another unit than m/s2 used?
The global CFM (Constraint Force Mixing). The default of ODE in my simualtion leads to bad results.
The time steps in the integrator dWorldStepFast1 (dWorldStep is to slow). I could not use my frame rate. In tutorials often the fixed value 0.1 is used.
My simulation are walls build with cubes and a worm build as a chain with joints.
ODE has a very good documentation and is open source.
On the other hand in Tokamak all simulations are very stable and look like what you would expect. Tokamak seems for me more performant than ODE (but I have no explicit proof).
I will now compare Newton with Tokamak. ODE is for me out of scope.
In ODE it is very difficult to adjust the parameters that the behaviour of your simulation is what you would expect.
As example following parameters.
The gravitation. Values of -0.5 are in tutorials used. Setting it to -9.1 often leads to unstable behaviour. But why should g be another value than -9.1 or is another unit than m/s2 used?
The global CFM (Constraint Force Mixing). The default of ODE in my simualtion leads to bad results.
The time steps in the integrator dWorldStepFast1 (dWorldStep is to slow). I could not use my frame rate. In tutorials often the fixed value 0.1 is used.
My simulation are walls build with cubes and a worm build as a chain with joints.
ODE has a very good documentation and is open source.
On the other hand in Tokamak all simulations are very stable and look like what you would expect. Tokamak seems for me more performant than ODE (but I have no explicit proof).
I will now compare Newton with Tokamak. ODE is for me out of scope.
puh: I won't release source YET, but I promise you I will... (cause in current state it wouldn't be much use to you)
DreiDe:
Gravity -- Right now, I'm using (in my engine) a variable gravity of -0.2 on up to -33.0 gravity setting and it always works fine. Not sure what you did wrong(?)
Framerate -- the trick is to update every 10ms (regardless of framerate) so if you're getting 60 fps, you'll notice that every frame, you will update 1.66 times (which means some frames will update once and some will update twice) ... if you're getting 200fps, only every other frame will update. If you're getting 10fps, that means that you will update 10 times every frame. When I say "update" -- I mean call dWorldStep1
---------------
For a good example (and sourcecode) of ODE in action: http://www.sjbrown.co.uk/buggy.html
In there, you can get a good idea of almost all of ODE elements (accept for per-triangle collisions)
There's also another program called "Juice" written by Nate, and this program is pretty cool because you can setup a ragdoll system in the simulation (the bodies and the joints) and then toss the model around the world (you can try different gravities too, but default -9.8 is just fine)
DreiDe:
Gravity -- Right now, I'm using (in my engine) a variable gravity of -0.2 on up to -33.0 gravity setting and it always works fine. Not sure what you did wrong(?)
Framerate -- the trick is to update every 10ms (regardless of framerate) so if you're getting 60 fps, you'll notice that every frame, you will update 1.66 times (which means some frames will update once and some will update twice) ... if you're getting 200fps, only every other frame will update. If you're getting 10fps, that means that you will update 10 times every frame. When I say "update" -- I mean call dWorldStep1
---------------
For a good example (and sourcecode) of ODE in action: http://www.sjbrown.co.uk/buggy.html
In there, you can get a good idea of almost all of ODE elements (accept for per-triangle collisions)
There's also another program called "Juice" written by Nate, and this program is pretty cool because you can setup a ragdoll system in the simulation (the bodies and the joints) and then toss the model around the world (you can try different gravities too, but default -9.8 is just fine)