How to hide ITextSceneNode

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
aungsithu
Posts: 39
Joined: Thu Sep 04, 2008 2:14 am
Location: Singapore
Contact:

How to hide ITextSceneNode

Post by aungsithu »

Hi,

I've some objects with some text displayed on top.
I'm using ITextSceneNode and place the text above the object's pos.

What happen is since these objects are moving in the scene, sometimes they are behind some other objects and cannot be seen. But the problem is the text above that object is always visible.

How can I hide my text if the object is not visible in the scene?

Thanks in advance
Aung Sithu
*** Check out my latest book, Beginner's guide to Irrlicht 3D engine: http://bit.ly/rSnm4O
Company: http://rivaledge.sg
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

Hmmm you'd have to come up with some system yourself i think... somehow determine whether the object is visible to the player and if it's not set the text node to invisible. Not entirely sure how you'd go about doing that though!

Alternatively you could create a new type of text scene node which doesn't render on top of everything and instead renders only when visible. Not sure if you could achieve that with the current text scene node or not by setting material params to do with the z buffer.
Image Image Image
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

if I remember correctly the default z-buffer flag is false for text scene nodes...
try to enable z-buffer for it:

Code: Select all

txtNode->setMaterialFlag(EMF_ZBUFFER, true);
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
B@z
Posts: 876
Joined: Thu Jan 31, 2008 5:05 pm
Location: Hungary

Post by B@z »

acki: i dont think that works, i tried that too.
didn't work for me. aungsithu try it too xD

well i think you should send a ray from the camera, to the model, and just set visibility to false if there is an obstacle
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

B@z wrote:acki: i dont think that works, i tried that too.
didn't work for me. aungsithu try it too xD
yes, you're right...
I had the billboard in mind, where I had this problem some time ago, but its default was changed to true meanwhile... ;)

I'm not sure why the text scene node doesn't react on the zbuffer flag though, maybe there is a reason for this ??? :shock:
or maybe it's simply a bug ??? :lol:
B@z wrote:well i think you should send a ray from the camera, to the model, and just set visibility to false if there is an obstacle
ok, but if you have many text scene nodes then this would cause some overheat, doesn't it ???
well, if it is the only way to do this... :?
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Eigen
Competition winner
Posts: 375
Joined: Fri Jan 27, 2006 2:01 pm
Location: Estonia
Contact:

Post by Eigen »

No need for casting a ray every frame. You could do it like once a second or so.
B@z
Posts: 876
Joined: Thu Jan 31, 2008 5:05 pm
Location: Hungary

Post by B@z »

yeah it would be cool if the zbuffer flag work..

well ray casting... didn't cause problem to me xD yet... xD
but the little problem with that is if you have the collision manager collide your camera, then it won't show the text node if youre near to the wall.
so you have to move the ray a little.
aungsithu
Posts: 39
Joined: Thu Sep 04, 2008 2:14 am
Location: Singapore
Contact:

Post by aungsithu »

@Acki:

Code: Select all

txtNode->setMaterialFlag(EMF_ZBUFFER, true);
This doesn't work for me also. :(

I want to try that ray casting too.
Can anybody give a basic idea of implementing ray casting in Irrlicht?

Thanks
Aung Sithu
*** Check out my latest book, Beginner's guide to Irrlicht 3D engine: http://bit.ly/rSnm4O
Company: http://rivaledge.sg
Frank Dodd
Posts: 208
Joined: Sun Apr 02, 2006 9:20 pm

Post by Frank Dodd »

I use a couple of lines like: -

Code: Select all

   line3d< f32 > ray(  vectorStart.x, vectorStart.y, vectorStart.z,
                        vectorEnd.x, vectorEnd.y, vectorEnd.z );
    ISceneNode * collisionNode = smgr->getSceneCollisionManager()->getSceneNodeFromRayBB( ray );
in my FreeBasic Irrlicht wrapper. I think Eigens comment is certainly noteworthy too, if you have ten labeled objects in your scene you could test one a frame or something.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

CTextSceneNode use uses Font->draw() to render the text. This is a purely 2D method, which doesn't take into account z depth.

There's also addBillboardTextSceneNode(), which renders the text onto a billboard. This does use z depth, but the billboard then scales with distance, and doesn't look very nice anyway.

An occlusion check might be good enough: this is the trivial case.

Code: Select all

#include "irrlicht.h"
#include <math.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

int main()
{
	IrrlichtDevice *device = createDevice( EDT_OPENGL,
								 dimension2d<s32>(800, 600),
								 32);
	ISceneManager* smgr  = device->getSceneManager();
	IVideoDriver* driver = device->getVideoDriver();

	ICameraSceneNode * camera = smgr->addCameraSceneNode();

	ISceneNode * cube1 = smgr->addCubeSceneNode();
	cube1->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
	cube1->setMaterialFlag(video::EMF_LIGHTING, false);
	cube1->setPosition(vector3df(0, 0, 40));


	ISceneNode * cube2 = smgr->addCubeSceneNode();
	cube2->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
	cube2->setMaterialFlag(video::EMF_LIGHTING, false);

	ITextSceneNode * text = smgr->addTextSceneNode(smgr->getGUIEnvironment()->getBuiltInFont(), stringw("Test").c_str());
	text->setParent(cube2);
	text->setPosition(vector3df(0, 8, 0));

	const u32 start = device->getTimer()->getTime();
	while (device->run())
	{
		const u32 now = device->getTimer()->getTime();
		const f32 depth = 40.f + 20.f * sin((f32)((now - start) % 2000) / 2000.f * 2.f * PI);
		cube2->setPosition(vector3df(5, 5, depth));
		cube2->updateAbsolutePosition();

		line3df rayToCube(camera->getAbsolutePosition(), cube2->getAbsolutePosition());
		if(cube2 == smgr->getSceneCollisionManager()->getSceneNodeFromRayBB(rayToCube))
			text->setVisible(true);
		else
			text->setVisible(false);

		driver->beginScene(true, true, video::SColor(0,100,100,100));
		smgr->drawAll();
		driver->endScene();
	}

	device->drop();
} 
If you're working inside (e.g.) a level mesh, then have a look in example 07.Collision/main.cpp. This uses getCollisionPoint() to test collision of a ray with a level mesh.

If you do that as well using the same camera-to-object ray (I'd do it after the bounding box check, since it's more expensive) then if you get a hit with the level mesh, you can assume that it's occluding the object of interest.

Both of these tests are very gross, and only test on a single ray to the centre of the object of interest. It's really up to you whether this is good enough, or whether you have to do more ray tests, or find another method of testing for occlusion.
Last edited by rogerborg on Thu Oct 30, 2008 1:07 pm, edited 1 time in total.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
B@z
Posts: 876
Joined: Thu Jan 31, 2008 5:05 pm
Location: Hungary

Post by B@z »

my code:

Code: Select all

			vector3df point;
			triangle3df tri;
			if (!smgr->getSceneCollisionManager()->getCollisionPoint(line3df(smgr->getActiveCamera()->getPosition()+MoveVector(vector3df(0,player->getRotation(),0),20), player[i].getPosition()), cMap.getTriangleSelector(),point,tri) &&
				player->getPosition().getDistanceFrom(players[i].getPosition()) < 650)
			{
                            players[i].textNode->setVisible(false);
			}
                        else players[i].textNode->setVisible(true);
oh MoveRotation has two parameters, first is the rotation, and the second is the length, and gives back a vector.
just a simple function what i wrote xD
aungsithu
Posts: 39
Joined: Thu Sep 04, 2008 2:14 am
Location: Singapore
Contact:

Post by aungsithu »

Thank you everyone.
I'll try it out and will let you know the results.

Cheers
Aung Sithu
*** Check out my latest book, Beginner's guide to Irrlicht 3D engine: http://bit.ly/rSnm4O
Company: http://rivaledge.sg
aungsithu
Posts: 39
Joined: Thu Sep 04, 2008 2:14 am
Location: Singapore
Contact:

Post by aungsithu »

OK. I gonna use that occlusion check.
That looks fit for me.
Thank you everybody..
Aung Sithu
*** Check out my latest book, Beginner's guide to Irrlicht 3D engine: http://bit.ly/rSnm4O
Company: http://rivaledge.sg
Post Reply