also is there anyway to do the same with rotations?.
i just wish i understude more about 3d code lol. i mean i know C++ but this is almost another laungauge XD.
![Smile :)](./images/smilies/icon_smile.gif)
Code: Select all
Q3. How do I represent a matrix using the C/C++ programming languages?
-----------------------------------------------------------------------
The simplest way of defining a matrix using the C/C++ programming
languages is to make use of the "typedef" keyword. Both 3x3 and 4x4
matrices may be defined in this way ie:
typedef float MATRIX3[9];
typedef float MATRIX4[16];
Since each type of matrix has dimensions 3x3 and 4x4, this requires
9 and 16 data elements respectively.
At first glance, the use of a single linear array of data values may
seem counter-intuitive. The use of two dimensional arrays may seem
more convenient ie.
typedef float MATRIX3[3][3];
typedef float MATRIX4[4][4];
However, the use of two reference systems for each matrix element
very often leads to confusion. With mathemetics, the order is row
first (i), column second (j) ie.
Mij
Using C/C++, this becomes
matrix[j][i]
Using two dimensional arrays also incurs a CPU performance penalty in
that C compilers will often make use of multiplication operations to
resolve array index operations.
So, it is more efficient to stick with linear arrays. However, one issue
still remains to be resolved. How is an two dimensional matrix mapped
onto a linear array? Since there are only two methods (row first/column
second or column first/row column).
The performance differences between the two are subtle. If all for-next
loops are unravelled, then there is very little difference in the
performance for operations such as matrix-matrix multiplication.
Using the C/C++ programming languages the linear ordering of each
matrix is as follows:
mat[0] = M mat[3] = M
00 03
mat[12] = M mat[15] = M
30 33
| 0 1 2 3 |
| | | 0 1 2 |
| 4 5 6 7 | | |
M = | | M = | 3 4 5 |
| 8 9 10 11 | | |
| | | 6 7 8 |
| 12 13 14 15 |
Code: Select all
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib, "Irrlicht.lib")
#endif
#include <irrlicht.h>
#include "driverChoice.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
vector3df GetIrrIn(ISceneNode* node)
{
matrix4 mat = node->getRelativeTransformation();
vector3df in(mat[8],mat[9],mat[10]);
in.normalize();
return in;
}
vector3df GetIrrUp(ISceneNode* node)
{
matrix4 mat = node->getRelativeTransformation();
vector3df up(mat[4],mat[5],mat[6]);
up.normalize();
return up;
}
vector3df GetIrrLeft(ISceneNode* node)
{
matrix4 mat = node->getRelativeTransformation();
vector3df left(mat[0],mat[1],mat[2]);
left.normalize();
return left;
}
vector3df GetPointInFront(ISceneNode* node, float distance)
{
vector3df p = node->getPosition();
p += distance * GetIrrIn(node);
return p;
};
vector3df GetPointInBack(ISceneNode* node,float distance)
{
vector3df p = node->getPosition();
p -= distance * GetIrrIn(node);
return p;
};
vector3df GetPointAbove(ISceneNode* node,float distance)
{
vector3df p = node->getPosition();
p += distance * GetIrrUp(node);
return p;
};
vector3df GetPointBelow(ISceneNode* node, float distance)
{
vector3df p = node->getPosition();
p -= distance * GetIrrUp(node);
return p;
};
vector3df GetPointInFrontAndAbove(ISceneNode* node,float d, float u)
{
vector3df p = GetPointInFront(node,d);
p.Y = GetPointAbove(node,u).Y;
return p;
};
vector3df GetPointInBackAndAbove(ISceneNode* node,float d, float u)
{
vector3df p = GetPointInBack(node,d);
p.Y = GetPointAbove(node,u).Y;
return p;
};
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
int main()
{
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice(driverType,
core::dimension2d<u32>(1000, 700), 16, false, false, false, &receiver);
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
IAnimatedMesh* usership = smgr->getMesh("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/Space_Ship_23.3DS");
if (!usership)
{
device->drop();
return 1;
}
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode(usership);
if (node)
{
node->setMaterialFlag(EMF_LIGHTING, false);
node->setMaterialTexture( 0, driver->getTexture("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/Ship_23_Texmap.png") );
node->setScale(core::vector3df(.1f,.1f,.1f));
}
IAnimatedMesh* planeback = smgr->getMesh("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/plane.3DS");
if (!planeback)
{
device->drop();
return 1;
}
IAnimatedMeshSceneNode* planeNode = smgr->addAnimatedMeshSceneNode(planeback);
if (planeNode)
{
planeNode->setMaterialFlag(EMF_LIGHTING, false);
planeNode->setMaterialTexture( 0, driver->getTexture("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/Spacescape.jpg") );
planeNode->setScale(core::vector3df(30.f,30.f,30.f));
}
ISceneNode* plane = smgr->addSkyBoxSceneNode(
driver->getTexture("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/Spacescape.jpg"),
driver->getTexture("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/Spacescape.jpg"),
driver->getTexture("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/Spacescape.jpg"),
driver->getTexture("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/Spacescape.jpg"),
driver->getTexture("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/Spacescape.jpg"),
driver->getTexture("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/Spacescape.jpg"));;
//partical system
scene::IParticleSystemSceneNode* ps = smgr->addParticleSystemSceneNode();
scene::IParticleEmitter* em = ps->createBoxEmitter(
core::aabbox3d<f32>(2,2,2,2,2,2), // emitter size
core::vector3df(0.08f,0.00f,0.0f), // initial direction
80,100, // emit rate
video::SColor(0,255,255,255), // darkest color
video::SColor(0,255,255,255), // brightest color
800,2000,90, // min and max age, angle
core::dimension2df(1.f,1.f), // min size
core::dimension2df(2.f,2.f)); // max size
ps->setEmitter(em); // this grabs the emitter
em->drop(); // so we can drop it here without deleting it
scene::IParticleAffector* paf = ps->createFadeOutParticleAffector();
ps->addAffector(paf); // same goes for the affector
paf->drop();
ps->setPosition(core::vector3df(-70,60,40));
ps->setScale(core::vector3df(2,2,2));
ps->setMaterialFlag(video::EMF_LIGHTING, false);
ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
ps->setMaterialTexture(0, driver->getTexture("C:/Users/Jordan/Documents/Visual Studio 2010/Projects/irrlichttest/Debug/fire.bmp"));
ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);
//load camera at the right distance from the model and remove cursor
ICameraSceneNode* camera = smgr->addCameraSceneNode(0, vector3df(-50,60,50));
device->getCursorControl()->setVisible(false);
int lastFPS = -1;
u32 then = device->getTimer()->getTime();
// This is the movemen speed in units per second.
const f32 MOVEMENT_SPEED = 1.f;
const f32 ROTATION_SPEED = 100.f;
const f32 ROTATION_SPEED2 = -100.f;
const f32 MAX_THRUST = 6.f;
const f32 MIN_THRUST = 0.f;
const f32 CAMERA_BACK = 500.0;
const f32 CAMERA_UP = 500.0;
float thrust = 0;
float rotat = ROTATION_SPEED;
float rotat2 = 0;
int a = 0;
vector3df rotation = node->getRotation();
vector3df nodePos = GetIrrIn(node);
vector3df movingVector;
while(device->run())
{
// Work out a frame delta time.
const u32 now = device->getTimer()->getTime();
const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
then = now;
// thrust
if(receiver.IsKeyDown(irr::KEY_KEY_W))
{
if (thrust == 0)
{
//take this out of the if and else statments and put the if and else in comments and the drift code will work.
//this bit of code was my atempt to make it not jump when you press w but the rotation of the old vector is messed lol
nodePos = GetIrrIn(node);
}
else
{
if (a = 5 && nodePos != GetIrrIn(node))
{
movingVector = nodePos;
movingVector.X += 0.1;
nodePos = movingVector;
}
else
{
a = 0;
}
}
thrust += MOVEMENT_SPEED * frameDeltaTime;
}
if(receiver.IsKeyDown(irr::KEY_KEY_S))
{
thrust -= MOVEMENT_SPEED * frameDeltaTime;
}
// rotate node left / right
if(receiver.IsKeyDown(irr::KEY_KEY_A))
{
//rotat = ROTATION_SPEED2 * frameDeltaTime;
rotat2 = ROTATION_SPEED2 * frameDeltaTime;
a = 5;
}
else if (!(receiver.IsKeyDown(KEY_KEY_D)))
{
rotat2 = 0;
rotat = 0;
}
if(receiver.IsKeyDown(irr::KEY_KEY_D))
{
rotat = ROTATION_SPEED * frameDeltaTime;
}
else if (!(receiver.IsKeyDown(KEY_KEY_A)))
{
rotat = 0;
}
// tilt up / down
if(receiver.IsKeyDown(irr::KEY_KEY_Z))
{
rotation.X -= ROTATION_SPEED * frameDeltaTime;
node->setRotation(rotation);
}
if(receiver.IsKeyDown(irr::KEY_KEY_X))
{
rotation.X += ROTATION_SPEED * frameDeltaTime;
node->setRotation(rotation);
}
//if trust goes over max thrust then set it to max thrust. if trust goes below min trust. set trust to min thrust
if (thrust > MAX_THRUST) thrust = MAX_THRUST;
if (thrust < MIN_THRUST) thrust = MIN_THRUST;
// set the nodes rotation / position
node->setRotation(node->getRotation() + GetIrrUp(node) * rotat);
node->setRotation(node->getRotation() + GetIrrUp(node) * rotat2);
node->setPosition(node->getPosition() + nodePos * thrust);
camera->setPosition(camera->getPosition() + nodePos * thrust);
/*Set camera to look at node*/
camera->setTarget(node->getPosition());
driver->beginScene(true, true, video::SColor(255,113,113,133));
smgr->drawAll(); // draw the 3d scene
device->getGUIEnvironment()->drawAll(); // draw the gui environment (the l
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw tmp(L"Movement Example - Irrlicht Engine [");
tmp += driver->getName();
tmp += L"] fps: ";
tmp += fps;
device->setWindowCaption(tmp.c_str());
lastFPS = fps;
}
}
/*
In the end, delete the Irrlicht device.
*/
device->drop();
return 0;
}
/*
That's it. Compile and play around with the program.
**/