Tokamak integration
Tokamak integration
I am trying to create the generic "falling blocks" physics demo in irrlich to give myself a quick introduction to both. I'm using the "Enhancing the engine" tutorial as a basic to create my blocks, and this tokamak tutorial here[url] for the physics portion.
The only problem I'm having is transferring the translation matrix from tokamak to the irrlich objects. Has anyone else made any progress integrating tokamak (or any other physics engine)?
Thanks in advance
¿?
The only problem I'm having is transferring the translation matrix from tokamak to the irrlich objects. Has anyone else made any progress integrating tokamak (or any other physics engine)?
Thanks in advance
¿?
-
- Posts: 118
- Joined: Thu Sep 18, 2003 10:05 pm
- Location: switzerland
But how do I set the matrix equal to the value returned by tokamak? Here's the code right now:
Code: Select all
neT3 t = gCubes[i]->GetTransform();
irr::core::matrix4 mat = CubeNode[i]->getAbsoluteTransformation();
mat(0,0) = t.rot[0][0];
mat(0,1) = t.rot[0][1];
mat(0,2) = t.rot[0][2];
mat(0,3) = 0;
mat(1,0) = t.rot[1][0];
mat(1,1) = t.rot[1][1];
mat(1,2) = t.rot[1][2];
mat(1,3) = 0;
mat(2,0) = t.rot[2][0];
mat(2,1) = t.rot[2][1];
mat(2,2) = t.rot[2][2];
mat(2,3) = 0;
mat(3,0) = t.pos[0];
mat(3,1) = t.pos[1];
mat(3,2) = t.pos[2];
mat(3,3) = 1.0;
-
- Posts: 118
- Joined: Thu Sep 18, 2003 10:05 pm
- Location: switzerland
Ouups, your right thats no mointer returned, hmm...
seems there's no method to get access to the matrix
but there are setPosition and serRotation methods,
well... maybe niko could add an interface to set the transformation matrices then? in the next version? would be really handy for physic plugins...
But meanwhile you could still extend ISceneNode and build your own node with access to the node, and copy past the code from niko's implementation classes... a bit complicated i think ...
seems there's no method to get access to the matrix
but there are setPosition and serRotation methods,
well... maybe niko could add an interface to set the transformation matrices then? in the next version? would be really handy for physic plugins...
But meanwhile you could still extend ISceneNode and build your own node with access to the node, and copy past the code from niko's implementation classes... a bit complicated i think ...
OK, I can get the position stuff working using the Node->setPosition() method:
if I set the AbsoluteTransformation matrix, it completely wigs out, so I want to use the setRotation method. This will make it easier for everyone else to.
The question is, how to convert from the translation matrix to angles? I can't seem to find any angle methods that work in tokamak's API, so is there an easy mathmatical way of doing this?
Code: Select all
neV3 p = gCubes[i]->GetPos();
TempVect.X = p[0];
TempVect.Y = p[1];
TempVect.Z = p[2];
CubeNode[i]->setPosition(TempVect);
The question is, how to convert from the translation matrix to angles? I can't seem to find any angle methods that work in tokamak's API, so is there an easy mathmatical way of doing this?
Woo, got it!!!
I need to majorly clean up the code, then I'll upload it. Here's a quck executable though:
http://enigmatic.shackspace.com/boxdrop.zip
Basicly, the tokamak object has a getRotationQ() function that returns a X, Y, Z, W matrix that corrisponds to the rotation about the respective axis (in radians). I don't know what the W is though. Any ideas?
Quick key guide to demo:
Alt+F4 - exit
Arrow keys - move
mouse - look
(it's using the FPS camera, so no fancy stuff there)
I need to majorly clean up the code, then I'll upload it. Here's a quck executable though:
http://enigmatic.shackspace.com/boxdrop.zip
Basicly, the tokamak object has a getRotationQ() function that returns a X, Y, Z, W matrix that corrisponds to the rotation about the respective axis (in radians). I don't know what the W is though. Any ideas?
Quick key guide to demo:
Alt+F4 - exit
Arrow keys - move
mouse - look
(it's using the FPS camera, so no fancy stuff there)
-
- Posts: 108
- Joined: Fri Aug 22, 2003 1:04 pm
- Location: Kerkrade, Netherlands
- Contact:
[quote="enigmatic"]
Basicly, the tokamak object has a getRotationQ() function that returns a X, Y, Z, W matrix that corrisponds to the rotation about the respective axis (in radians). I don't know what the W is though. Any ideas?
quote]
cool!
could be that the tokamak function returns the rotation quaternion. if you'r into maths :
http://www.gamedev.net/reference/articl ... le1095.asp
Basicly, the tokamak object has a getRotationQ() function that returns a X, Y, Z, W matrix that corrisponds to the rotation about the respective axis (in radians). I don't know what the W is though. Any ideas?
quote]
cool!
could be that the tokamak function returns the rotation quaternion. if you'r into maths :
http://www.gamedev.net/reference/articl ... le1095.asp
Tutorial
I'd sent the source to Niko. Hopefully he'll get it up, or at least do something with it
Here's the file: http://enigmatic.shackspace.com/boxdrop.zip (388k)
And here's the pieces of the tutorial that matter:
These come from both tutorials. The irrlicht and tokamk libraries are self
explanitary, while the others are a little strange. These are used for the
timing functions. Nothing to magical beyond thatInclusion of the specific libraries. Again, the abbaration is the
winmm library, used for the timeGetTime() function.Defines to make playing with the simulation easier.
PI is used to convert from Degrees to Radians.
CUBECOUNT is the number of cubes to stack
CUBEX/Y/Z are the dimentions of the cube (any size box you want)
CUBEMASS is the mass of the cube
FLOORSIZE is the size of the square "floor" that the cubes fall on.
Play with the cube information and see what happens (to heavy, or to
small cubes seem to fall through the floor)tok - Global variables for Tokamak:
First the simulator itselfThe cube pointer arrayTimer variablestok - almost straight from the tok tutorial, we initialize the physics engine:Vary the position so the cubes don't all exactly stack on top of each other
(makes for a more interesting simulation)
MC - You may need to play with the randomization stuff, since your cube may be to big to be easily destabelizedOK, the main function, where the meat is. Here's where I had the most fun.tok - timer stuffMC - I needed a vector3df to pass to the Node movement functions MC - I moved the camera so the initial view is more interesting then turned it toward the origin, there the cubes fall MC - This is a major step, in case it's not obvious. Initialize Tokamak MC - Here we set up our array of cubes then create them. Make sure you DO NOT drop() the cubes, since we need to use the pointer to refer back to the cubes to position themMC - I'm one of those programmers that will fit 2 or more commands on one line if I can. Plus, I think this is a really cute way of calling and dropping a node without using a variable. I use the magic of C++ to create a new Node and drop that same node in the same look. If I was doing this the long way I would need a PhysicsFloorNode pointertok - Initialize the timer and the variable to count the last number of milliseconds. this makes sure there isn't a wierd jump in the program.Now the fun begins.tok - Find out how much time has elapsed since we were last calledtok - Prevent the elapsed time from being more than 20% greater or less than the previous elapsed time.MC - here where the real magic happens. We loop through each cube;
First, we get the position from the Tokamak cube
We set up out temporary vector
And set the position of the cube that Irrlicht is going to drawLast, we get the rotation from the Tokamak cube. This is a the rotation quaternion, I believe More information is found here:
http://www.gamedev.net/reference/articl ... le1095.asp
(Thanks to unnamed forum user)
Again, the temporary vector is set
we convert it to degrees and set the Irrlicht cube's rotationtok - When we're one, we kill the physics engineMC - And drop all the node pointers that we don't need anymore
And there you have it...download the source and play with it if you'd like. It's simply a .cpp file, so you can adapt it to whatever IDE you'd like
Here's the file: http://enigmatic.shackspace.com/boxdrop.zip (388k)
And here's the pieces of the tutorial that matter:
IncludesIrrlicht/Tokamak integration tutorial by enigmatic (enigmatic@shackmail.com)
Code based off Irrlicht tutorial 3, Creating a Custom Scene Node
Found here: http://irrlicht.sourceforge.net/tut003.html
With tokamak information taken from Adam Dawes' cube stacking
tutorial found here: http://www.adamdawes.com/programming/to ... Cubes.html
I will go over the entire code, however the vast majority of it comes from one
tutorial or the other. I will note which is which, and any alterations I have
made. I will also note my own code.
A very important note is that irrlicht and tokamak use the same names for some
data types. This causes all sorts of errors. Thankfully irrlicht has been written
with integration in mind, and is built using namespaces. Tokamak, on the other had,
does not. This means that you are forced to reference the irrlich namespace rather
use the "using" keyword to simplify tasks. You do this by placing "irr::" in front
of all irrlicht specific calls.
I'm going to concentrate on the integration stuff, and skim over the rest, since I
don't want to cover what's already been taken care of thanks to the tutorials above.
Irr denotes Irrlicht
Tok denotes Tokamak
These come from both tutorials. The irrlicht and tokamk libraries are self
explanitary, while the others are a little strange. These are used for the
timing functions. Nothing to magical beyond that
Code: Select all
#include <irrlicht.h>
#include <tokamak.h>
#include <windows.h>
#include <time.h>
winmm library, used for the timeGetTime() function.
Code: Select all
#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")
PI is used to convert from Degrees to Radians.
CUBECOUNT is the number of cubes to stack
CUBEX/Y/Z are the dimentions of the cube (any size box you want)
CUBEMASS is the mass of the cube
FLOORSIZE is the size of the square "floor" that the cubes fall on.
Play with the cube information and see what happens (to heavy, or to
small cubes seem to fall through the floor)
Code: Select all
#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
First the simulator itself
Code: Select all
neSimulator *gSim = NULL;
Code: Select all
neRigidBody *gCubes[CUBECOUNT];neAnimatedBody *gFloor = NULL;
Code: Select all
bool gbUseHFTimer;
INT64 gCurrentTime;
float gfTimeScale;
Code: Select all
bool InitPhysics(void)
(makes for a more interesting simulation)
MC - You may need to play with the randomization stuff, since your cube may be to big to be easily destabelized
Code: Select all
pos.Set((rand()%10) / 20.0f * CUBEX, 4.0f + i * (CUBEY + 1) , rand()%10) / 20.0f * CUBEZ);
gCubes[i]->SetPos(pos);
Code: Select all
int main()
{
Code: Select all
float fElapsed;
static float fLastElapsed;
int i;
Code: Select all
irr::core::vector3df TempVect;
Code: Select all
camera->setPosition(irr::core::vector3df(20,30,20));
camera->setTarget(irr::core::vector3df(-20,-30,-20));
Code: Select all
InitPhysics();
Code: Select all
PhysicsCubeNode *CubeNode[CUBECOUNT];
for (i=0; i<CUBECOUNT;i++)
{
CubeNode[i] = new PhysicsCubeNode(smgr->getRootSceneNode(), smgr, 666);
}
Code: Select all
(new PhysicsFloorNode(smgr->getRootSceneNode(), smgr, 666))->drop();
Code: Select all
InitTimer();
fLastElapsed = 0;
Code: Select all
while(device->run())
{
Code: Select all
fElapsed = GetElapsedTime();
Code: Select all
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);
Code: Select all
for (i=0; i<CUBECOUNT; i++)
{
We set up out temporary vector
And set the position of the cube that Irrlicht is going to draw
Code: Select all
neV3 p = gCubes[i]->GetPos();
TempVect.X = p[0];
TempVect.Y = p[1];
TempVect.Z = p[2];
CubeNode[i]->setPosition(TempVect);
http://www.gamedev.net/reference/articl ... le1095.asp
(Thanks to unnamed forum user)
Again, the temporary vector is set
we convert it to degrees and set the Irrlicht cube's rotation
Code: Select all
neQ q = gCubes[i]->GetRotationQ();
TempVect.Y = q.Y;
TempVect.X = q.X;
TempVect.Z = q.Z;
TempVect *= 180 / PI;
CubeNode[i]->setRotation(TempVect);
}
Code: Select all
KillPhysics();
Code: Select all
for (i=0; i<CUBECOUNT;i++)
CubeNode[i]->drop();
I don't think that the rotation information is stored directly in the (x,y,z) triple in a quaternion. To prove this, I copied the code below from a quaternion class. So if you have to give the Irrlicht engine the rotations by the axes X,Y,Z, you have to calculate these angles from the (x,y,z,w) values... there should be several ways to do this, like transforming the quat to a matrix and passing that to Irr, or converting it to an axis-angle pair, and transfroming an identity matrix with them. I haven't tried any of these, but I will have to, since the more complicated Tokamak stuff (like that falling RadDude ) just don't seem to work correctly.
Gonosz
Code: Select all
angle *= ( M_PI / 180.0 );
// Normalize the axis.
GLfloat factor = x * x + y * y + z * z;
assert( factor != 0 );
GLfloat scaleBy( 1.0 / sqrt( factor ) );
x = x * scaleBy;
y = y * scaleBy;
z = z * scaleBy;
// Build a quaternion!
d_val[ 0 ] = cos( angle / 2.0 );
GLfloat sinHalfAngle( sin( angle / 2.0 ) );
d_val[ 1 ] = x * sinHalfAngle;
d_val[ 2 ] = y * sinHalfAngle;
d_val[ 3 ] = z * sinHalfAngle;
I have solved the problem with the following code. If your class is a child of ISceneNode, you can access the transformation matrix easily (only be careful it's transposed)
http://www.extra.hu/i713/load/tokamak.jpg
To correct the tutorial, you have to put an 'Update(neRigidBody *gCube)' function into the PhysicsCubeNode class, and call that in the main() update cycle (from line 502)
Now the cubes will lie on the ground the way they always should've BTW I have copied the RadDude from Tokamak tut 9, and modified it to work with Irrlicht. If anyone is interested, I can post the source.
Gonosz
Code: Select all
neQ q = gCube->GetRotationQ();
neM4 neMatrix = q.BuildMatrix();
neMatrix.SetTranslation(gCube->GetPos());
for (int x=0; x < 4; x++)
{
for (int y=0; y < 4; y++)
{
AbsoluteTransformation(y,x) = neMatrix.M[x][y];
}
}
To correct the tutorial, you have to put an 'Update(neRigidBody *gCube)' function into the PhysicsCubeNode class, and call that in the main() update cycle (from line 502)
Now the cubes will lie on the ground the way they always should've BTW I have copied the RadDude from Tokamak tut 9, and modified it to work with Irrlicht. If anyone is interested, I can post the source.
Gonosz
Last edited by Gonosz on Thu Oct 30, 2003 2:07 pm, edited 1 time in total.