Box2D and Irrlicht

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
constchar*
Posts: 14
Joined: Thu Sep 20, 2007 3:57 am

Box2D and Irrlicht

Post by constchar* »

Hey guys, I created a test class that creates a circle in Box2D and a sphere in Irrlicht and fires it in the camera's direction.

I didn't bother with coding it too properly because it was a quick test, but it should be clear enough to learn how to use Box2D with Irrlicht.

Also WORLD_PHYS_SCALE is defined as 30.0f because Box2D measures the world in meters and in order to keep things on a smaller scale and consistent with Irrlicht's world coordinates I have to divide and multiply coordinates by WORLD_PHYS_SCALE where appropriate.

I hope this helps somebody.

Code: Select all

/* Header */

#ifndef _INCLUDE_TESTNODE_H_
#define _INCLUDE_TESTNODE_H_

#include "maze.h"

class World;

class TestNode
{
	
private:
	
	IMeshSceneNode* _Node;
	b2Body*	_Body;
	
	World* _World;
	
public:
	
	TestNode(World* world);
	~TestNode(void);
	
	void think(void);
	
};

#endif

/* Code file */

#include "maze.h"
#include "testnode.h"
#include "world.h"

TestNode::TestNode(World* world)
{
	
	ICameraSceneNode* cam = g_pIrrDevice->getSceneManager()->getActiveCamera();
	
	_Node = g_pIrrDevice->getSceneManager()->addSphereSceneNode(5.0f);
	g_pIrrDevice->getSceneManager()->addLightSceneNode(_Node);
	
	_Node->setPosition(
		vector3df( cam->getPosition().X, (WORLD_CELL_SIZE/2.0f), cam->getPosition().Z )
	);
	
	b2BodyDef bDef;
	bDef.type = b2_dynamicBody;
	bDef.allowSleep = true;
	bDef.position = b2Vec2( cam->getPosition().X / WORLD_PHYS_SCALE, cam->getPosition().Z / WORLD_PHYS_SCALE );
	
	b2CircleShape shape;
	shape.m_radius = 5.0f / WORLD_PHYS_SCALE;
	
	b2FixtureDef fxDef;
	fxDef.shape = &shape;
	fxDef.density = 1;
	fxDef.restitution = 0.75f;
	fxDef.friction = 0.5f;
	fxDef.userData = (void*)this;
	
	_Body = world->getPhysicalWorld()->CreateBody(&bDef);
	_Body->CreateFixture(&fxDef);
	
	vector3df vecDir;
	vecDir.X = cam->getTarget().X - cam->getPosition().X;
	vecDir.Y = cam->getTarget().Y - cam->getPosition().Y;
	vecDir.Z = cam->getTarget().Z - cam->getPosition().Z;
	vecDir.normalize();
	
	_Body->ApplyLinearImpulse(
		b2Vec2(vecDir.X, vecDir.Z),
		_Body->GetPosition()
	);
	
}

void TestNode::think(void)
{
	
	b2Vec2 physPos = _Body->GetPosition();
	vector3df irrPos = _Node->getPosition();
	
	irrPos.X = physPos.x * WORLD_PHYS_SCALE;
	irrPos.Z = physPos.y * WORLD_PHYS_SCALE;
	
 	_Node->setPosition(irrPos);
	
}
Brainsaw
Posts: 1242
Joined: Wed Jan 07, 2004 12:57 pm
Location: Bavaria

Post by Brainsaw »

That's nice. Are you planning to evolve this into a wrapper? I tried Box2D some time ago, but due to some initial trouble I went back to ODE.
Image
Dustbin::Games on the web: https://www.dustbin-online.de/
TheMrCerebro
Competition winner
Posts: 80
Joined: Tue Jun 29, 2010 10:06 pm
Location: Valencia, Spain

Post by TheMrCerebro »

Would be very nice to integrate the Box2D to Irrlitch but the problem is that Irrlicht is not entirely a 2D environment.

Can be and it is easy (see example of "constchar *"), but to rotate images, change the size of the font letters, ... is very limited. This case, and sorry for the Irrlicht engine, would be better to use the SFML library. I use it and works very well for 2D environment.
Follow me on twitter: @themrcerebro
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

I strongly disagree with that. Irrlicht can very easily draw rotated images and fonts. In fact, I have a simple Box2D implementation in irrlicht that has rotated images and the like
Image
TheMrCerebro
Competition winner
Posts: 80
Joined: Tue Jun 29, 2010 10:06 pm
Location: Valencia, Spain

Post by TheMrCerebro »

And I disagree with you because it shows a picture of that if you can, but does not display the code as is. :lol:

I only say that with the code as is now, you can not, you need to be modified. So I put the example of another library more specializing in 2D environments.
Follow me on twitter: @themrcerebro
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

You said it would be better to use SFML, when irrlicht is perfectly capable. Of course you need to add something, you also need to add something to do audio. But that doesn't mean another engine will be better because it has audio on default. I do agree SFML can do 2d better out of the box, but why change from something he seems familiar with, while 2d is so easy? Irrlicht was meant primarily as a 3D engine, but it can do much more, which is primarily left to the user. And to show you how easy rotated 2d images are:

Code: Select all

void draw2DImage(irr::video::IVideoDriver* driver, irr::video::ITexture* texture, irr::core::rect<irr::s32> sourceRect, irr::core::position2d<irr::s32> position, irr::core::position2d<irr::s32> rotationPoint = irr::core::position2d<irr::s32>(0,0), irr::f32 rotation = 0.0f, irr::core::vector2df scale = irr::core::vector2df(1,1), bool useAlphaChannel = true, irr::video::SColor color = irr::video::SColor(255,255,255,255)) {
	
	irr::video::SMaterial material;

	// Store and clear the projection matrix
	irr::core::matrix4 oldProjMat = driver->getTransform(irr::video::ETS_PROJECTION);
	driver->setTransform(irr::video::ETS_PROJECTION,irr::core::matrix4());
	
	// Store and clear the view matrix
	irr::core::matrix4 oldViewMat = driver->getTransform(irr::video::ETS_VIEW);
	driver->setTransform(irr::video::ETS_VIEW,irr::core::matrix4());

	// Find the positions of corners
	irr::core::vector2df corner[4];

	corner[0] = irr::core::vector2df(position.X,position.Y);
	corner[1] = irr::core::vector2df(position.X+sourceRect.getWidth()*scale.X,position.Y);
	corner[2] = irr::core::vector2df(position.X,position.Y+sourceRect.getHeight()*scale.Y);
	corner[3] = irr::core::vector2df(position.X+sourceRect.getWidth()*scale.X,position.Y+sourceRect.getHeight()*scale.Y);

	// Rotate corners
	if (rotation != 0.0f) 
		for (int x = 0; x < 4; x++)
			corner[x].rotateBy(rotation,irr::core::vector2df(rotationPoint.X, rotationPoint.Y));


	// Find the uv coordinates of the sourceRect
	irr::core::vector2df uvCorner[4];
	uvCorner[0] = irr::core::vector2df(sourceRect.UpperLeftCorner.X,sourceRect.UpperLeftCorner.Y);
	uvCorner[1] = irr::core::vector2df(sourceRect.LowerRightCorner.X,sourceRect.UpperLeftCorner.Y);
	uvCorner[2] = irr::core::vector2df(sourceRect.UpperLeftCorner.X,sourceRect.LowerRightCorner.Y);
	uvCorner[3] = irr::core::vector2df(sourceRect.LowerRightCorner.X,sourceRect.LowerRightCorner.Y);
	for (int x = 0; x < 4; x++) {
		float uvX = uvCorner[x].X/(float)texture->getSize().Width;
		float uvY = uvCorner[x].Y/(float)texture->getSize().Height;
		uvCorner[x] = irr::core::vector2df(uvX,uvY);
	}

	// Vertices for the image
	irr::video::S3DVertex vertices[4];
	irr::u16 indices[6] = { 0, 1, 2, 3 ,2 ,1 };

	// Convert pixels to world coordinates
	float screenWidth = driver->getScreenSize().Width;
	float screenHeight = driver->getScreenSize().Height;
	for (int x = 0; x < 4; x++) {
		float screenPosX = ((corner[x].X/screenWidth)-0.5f)*2.0f;
		float screenPosY = ((corner[x].Y/screenHeight)-0.5f)*-2.0f;
		vertices[x].Pos = irr::core::vector3df(screenPosX,screenPosY,1);
		vertices[x].TCoords = uvCorner[x];
		vertices[x].Color = color;
	}
	material.Lighting = false;
	material.ZWriteEnable = false;
	material.TextureLayer[0].Texture = texture;
	//material.TextureLayer[0].TextureWrap = irr::video::ETC_CLAMP;


	if (useAlphaChannel)
		material.MaterialType = irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL;
	else
		material.MaterialType = irr::video::EMT_SOLID;


	driver->setMaterial(material);
	driver->drawIndexedTriangleList(&vertices[0],4,&indices[0],2);

	// Restore projection and view matrices
	driver->setTransform(irr::video::ETS_PROJECTION,oldProjMat);
	driver->setTransform(irr::video::ETS_VIEW,oldViewMat);
}
TheMrCerebro
Competition winner
Posts: 80
Joined: Tue Jun 29, 2010 10:06 pm
Location: Valencia, Spain

Post by TheMrCerebro »

You said it would be better to use SFML, when irrlicht is perfectly capable.
But only for 2D environments !!!!!
I use more Irrlicht because it is more complete, but weakens in 2D.
that doesn't mean another engine will be better because it has audio on default
When I use the SFML only use the graphics library and BASS library for sound.
but why change from something he seems familiar with, while 2d is so easy?
I'm not saying that engine change, just show another more viable / alternative. I had to use that SFML library, because the performance fell sharply in Irrlicht and had a few commands for 2D.

This is not an attack on the Irrlicht engine!! :wink:

PD: Thanks for your code. :!:
Follow me on twitter: @themrcerebro
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

Ah, stupid me :lol:. I mistook your meaning, sorry if I came off as rude
constchar*
Posts: 14
Joined: Thu Sep 20, 2007 3:57 am

Post by constchar* »

Brainsaw wrote:That's nice. Are you planning to evolve this into a wrapper? I tried Box2D some time ago, but due to some initial trouble I went back to ODE.
Actually no, or at least not at first.
I'm developing a simple game engine that resembles Wolfenstein 3D and the like and I needed a collision detection solution and since the environment is essentially 2D I used Box2D, also I figured Box2D could produce more accurate and smooth collision detection then I could if I wrote it myself.

This would also work with other genres like platformers in a 3D environment but with 2D gameplay (e.g. New Super Mario Bros Wii).

EDIT:

Also Box2D uses angles in radians, and in my case objects rotate around the Y axis, so for example:

Code: Select all

vector3df rot = _Node->getRotation();
_Node->setRotation(rot.X, (f32)radToDeg(_physBody->GetAngle()), rot.Z);
Brainsaw
Posts: 1242
Joined: Wed Jan 07, 2004 12:57 pm
Location: Bavaria

Post by Brainsaw »

I've been thinking about writing a "2.5D" game sometime in the future, but the ODE does also provide a possibility to restrict movement to 2 dimensions, so I guess I would stay with my wrapper anyways.
Image
Dustbin::Games on the web: https://www.dustbin-online.de/
Post Reply