speech bubbles

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
schoolboy

speech bubbles

Post by schoolboy »

hello :)

I began recently with irrlicht.

i am very inspired of it. now i wont to make some kind of "speech bubbles" (you know what i mean?) this kind of bubbles over charakters with text in it.

i want to do this for a school projekt. there isn't much time left and i have to do a lot more work ... build classes for the use of databases and a few more :?

i have to do this with java and i choose bindenlicht for this .. i hape this was the right choise... could you help me with this ? maybe in c++ i am also familiar with this version of irrlicht. maybe you can give me some links from this board ... i used the search function but i didn't find topics that fit my problem

my main problem is how to do this .. wich classes i have to use .. how can i make them look everytime to the camera .. how can i attach this on a node ... or so that this is everytime over the char it has to be.

if this iss possible without the event manager? only to show text over a character which is directet to the camera?

i would be very pleased if you guys can give me some help .. this would give me some nights for sleep (this is serious), so i dont have to waste time for trying ... this is a serious emergency :oops:

it has to be done on Wednesday and i am already in time delay ...
Morrog
Posts: 58
Joined: Mon Dec 13, 2004 5:13 am

Post by Morrog »

You can do this two ways.

The first is with GUI/2D things. Basically all you do is draw (with GUI methods or 2D methods) the bubble over someone's head, and then draw the text. To find out where to draw the bubble you simply use:
irr::scene::ISceneCollisionManager::getScreenCoordinatesFrom3DPosition

That function will take a 3D point and project it into a 2D point for you. So if you found the 3D point above a person's head, you can use that function to convert that to the correct 2D position.

The second method is with billboards. Basically you generate the texture of the bubble and then use that on a billboard scene node and place it above someone's head. This will change with distance, so you might want to get the distance to the character and adjust the billboard's size based on that.
Guest

Post by Guest »

very very very thanks .. really!

i think the 2nd solution didnt meet my needs .. cuz i want to load the text from the data base.

the first is interesting to me ... i think (or better hope ) it is not necessary to scale the size from the distance... or maybe later ... if there is is complexer solution and more time for this.

that mean ... i use e.g.. guienv.addStaticText("foo", new Recti(1,1,2,2), true);

and i get the coords for Recti from the getScreenCoordinatesFrom3DPosition
function ?

should i call that function in

while(device.run())
{
}

because this has to be updatet every frame!
Morrog
Posts: 58
Joined: Mon Dec 13, 2004 5:13 am

Post by Morrog »

that mean ... i use e.g.. guienv.addStaticText("foo", new Recti(1,1,2,2), true);

and i get the coords for Recti from the getScreenCoordinatesFrom3DPosition
function ?
Yes, except you'll be doing:
IGUIStaticText *bubble = guienv->addStaticText(......);

and then in the loop you'll update the rectangle of bubble each frame by using the size of the bubble and the 2D position you get from getScreenCoordinatesFrom3DPosition.

And this solution does not require you change the size of the bubble based on distance, since it's just a GUI entity and therefore has no Z value.
Guest

Post by Guest »

thx!

i tryed this

Code: Select all

...
IGUIStaticText bubble =null;
int i= 1;

while(device.run())
    {
      ...

      bubble =  guienv.addStaticText("this is "+i+" a time" , new    Recti(100+i,100+i,200+i,200+i), true);
      i++;

      ...  
    }
  
i don't write the unnecessarily thinks.

this works but the only problem is that the new bubble (from the shift) is overwriting the other. how do i clean the old before i write the "shifted" one?
than i have all i need i think :)
Guest

schoolboy

Post by Guest »

ok before this problem is fixed .. i had to concentrate on the position of the bubble!

ok getScreenCoordinatesFrom3DPosition() needs a vector3df as parameter
i get this from my node with irr::scene::ISceneNode::getPosition ()

ok than i have a position2d and with this i colculate the coordiantes from my bubble (recti)

if i have the 2d position (100/200) my recti should be Recti(50,150,150,250)

now i had to get this in code
schoolboy

Post by schoolboy »

i have code this .. but that is not what i expect :lol:

i decided to use c++ code cuz it is easier to understand for all c++ guys here and for me

Code: Select all

...

ISceneCollisionManager* colman = smgr->getSceneCollisionManager();
	
	
	IGUIStaticText* bubble = NULL;
	position2d<s32> pos2d  = colman->getScreenCoordinatesFrom3DPosition(node->getPosition(), camera);	
	while(device->run())
	{
		
		...

		pos2d = colman->getScreenCoordinatesFrom3DPosition(node->getPosition(), camera);
	
		bubble =  guienv->addStaticText(L"this is  a time" ,             core::rect<s32>(pos2d.X+50,pos2d.X-50,pos2d.Y+50,pos2d.Y-50), true);

      ...
	}

but this dont show me the box on or over the char .. it do a lot funny thinks like change the size of this bubble box or shift it on an virtuell line diagonal on the srceen

the hole code:

Code: Select all

#include <irrlicht.h>


using namespace irr;


using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


#pragma comment(lib, "Irrlicht.lib")


int main()
{
	

	IrrlichtDevice *device =
		createDevice(EDT_SOFTWARE, dimension2d<s32>(800, 600), 32, false, false, 0);

	
	device->setWindowCaption(L"Wulverin's Angel of Death ");

	
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();

	
	IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
	IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );

	
	if (node)
	{
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setFrameLoop(0, 310);	
		node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );
	}

	
	scene::ICameraSceneNode* camera = 
		smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);
	camera->setPosition(core::vector3df(0,100,0));

	
	int i= 1;

    ISceneCollisionManager* colman = smgr->getSceneCollisionManager();
	
	
	IGUIStaticText* bubble = NULL;
	position2d<s32> pos2d  = colman->getScreenCoordinatesFrom3DPosition(node->getPosition(), camera);	
	while(device->run())
	{
		
		driver->beginScene(true, true, SColor(0,100,100,100));

		pos2d = colman->getScreenCoordinatesFrom3DPosition(node->getPosition(), camera);
	
		bubble =  guienv->addStaticText(L"this is  a time" ,  core::rect<s32>(pos2d.X+50,pos2d.X-50,pos2d.Y+50,pos2d.Y-50), true);
		//i++;

		smgr->drawAll();
		guienv->drawAll();

		driver->endScene();
	}

	
	device->drop();

	return 0;
}
here a litle image of the result of this code
Image
Guest

Post by Guest »

now i have it !!

i didn't watch exactly to the rect definition :oops:

irr::core::rect< T >::rect ( T x,T y,T x2,T y2)

hehe

changed code

Code: Select all

bubble =  guienv->addStaticText(L"this is  a time" ,  core::rect<s32>(pos2d.X-50,pos2d.Y-50,pos2d.X+50,pos2d.Y+50), true);
now it looks like this
Image

now i only have to know how to clean the old bubbles away!
bal
Posts: 829
Joined: Fri Jun 18, 2004 5:19 pm
Location: Geluwe, Belgium

Post by bal »

You only have to add the StaticText one time (before the draw loop)! Not every frame like you're doing now and thus creating a new StaticText object every frame.
General Tools List
General FAQ
System: AMD Barton 2600+, 512MB, 9600XT 256MB, WinXP + FC3
Guest

Post by Guest »

now i get the hole thing!

i only had to remove the element from the gui after drawing in the main loop
and a bit of shiftig the box so that it is over the char!

if some body is interestet in it ... or is able to make it look beter i post the code:

Code: Select all

#include <irrlicht.h>


using namespace irr;


using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


#pragma comment(lib, "Irrlicht.lib")


int main()
{
	

	IrrlichtDevice *device =
		createDevice(EDT_OPENGL, dimension2d<s32>(800, 600), 32, false, false, 0);

	
	device->setWindowCaption(L"Wulverin's Angel of Death ");

	
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();

	
	IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
	IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );

	
	if (node)
	{
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setFrameLoop(0, 310);	
		node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );
	}

	
	scene::ICameraSceneNode* camera = 
		smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);
	camera->setPosition(core::vector3df(0,100,0));

    // make the manager for the 3d 2d projection opperations
    ISceneCollisionManager* colman = smgr->getSceneCollisionManager();
	
	// make a bubble an get the 3d coords from the node
	IGUIStaticText* bubble = NULL;
	position2d<s32> pos2d  = colman->getScreenCoordinatesFrom3DPosition(node->getPosition(), camera);	
	while(device->run())
	{
		
		driver->beginScene(true, true, SColor(0,100,100,100));
		// save the 3d position and add 50 so the box is apearing over the char
		vector3d<f32> pos = node->getPosition();
		pos.set(pos.X, pos.Y+50, pos.Z),
		// update the position
		pos2d = colman->getScreenCoordinatesFrom3DPosition(pos, camera);
		bubble =  guienv->addStaticText(L"this is  a time" ,  core::rect<s32>(pos2d.X-50,pos2d.Y-50,pos2d.X+50,pos2d.Y+50), true, false);
		

		smgr->drawAll();
		guienv->drawAll();
		// important .. remove the bubble after drawing!
		bubble->remove();


		driver->endScene();
	}

	
	device->drop();

	return 0;
}

and a little picture :D
Image

do you have any suggestions to make it look better? please let me know!!!

have a nice Sunday!! :wink:
Guest

Post by Guest »

bal wrote:You only have to add the StaticText one time (before the draw loop)! Not every frame like you're doing now and thus creating a new StaticText object every frame.
but how do i update the position ?
bal
Posts: 829
Joined: Fri Jun 18, 2004 5:19 pm
Location: Geluwe, Belgium

Post by bal »

bubble->setPosition(...) would do.

But I suggest using the new ITextSceneNode for speech bubbles. It is demonstrated in the Shader demo. With the ITextSceneNode you can place text in 3D and that's exactly what you need I guess.
General Tools List
General FAQ
System: AMD Barton 2600+, 512MB, 9600XT 256MB, WinXP + FC3
Guest

Post by Guest »

bal wrote:bubble->setPosition(...) would do.

But I suggest using the new ITextSceneNode for speech bubbles. It is demonstrated in the Shader demo. With the ITextSceneNode you can place text in 3D and that's exactly what you need I guess.
very very very ... * 10^23 thx!!

your last post solved all my problems!!!! ... the other version work ... but i had hard problem to get this in java .. cuz there are some strang return type conversations

but with this way .. it goes in 5 minutes :X thx bal very very very much

is this a new feature in 0.7? this is not in 0.6 .. but i thought bindenlicht is in 0.6 ... i have real luck !!!
Morrog
Posts: 58
Joined: Mon Dec 13, 2004 5:13 am

Post by Morrog »

I forgot about textscenenode ;)
But you won't be able to do a background for the bubbles with textscenenode.
Post Reply