Improving the loadScene() command.

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Improving the loadScene() command.

Post by christianclavet »

The current loadscene command, load the entire scene with everything and doesnt give feedback at all. This also remove control from the user and make the application appear as if was frozen.

Since we can't really ask for a background loader without redesigning the
whole engine. Would be nice to have at least that:

An initial "loadScene_count()" command that -count- the nodes of the scene, but don't load anything at all

A "loadScene_nextNode()" type command that load the next occurence of a node in the current loaded scene in sequence. (mesh, terrain, occtree, light, etc.)

We could have a status function like "sceneloaded() "for example by checking that function that will return the remaining nodes to load. So
this could be used to determine the remaining items in the scene and could update the screen at each nodes loaded remaining. So easy to put in a user defined loop. (Refreshing, the screen at each step)

(Getting the value when ititiating the "loadScene()" command will get the number of remaining nodes when the load was started, giving the total numbers of nodes.)

I've already posted this on the features request on the sourceforge site.
Update: Just checked again the source code! Seen that you already have worked that out! Is the command readSceneNode() is exposed to the user? It does exactly that!

Code: Select all

//! Loads a scene. Note that the current scene is not cleared before.
bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer)
{
	if (!file)
	{
		os::Printer::log("Unable to open scene file", ELL_ERROR);
		_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
		return false;
	}

	io::IXMLReader* reader = FileSystem->createXMLReader(file);
	if (!reader)
	{
		os::Printer::log("Scene is not a valid XML file", file->getFileName(), ELL_ERROR);
		_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
		return false;
	}

	// for mesh loading, set collada loading attributes

	bool oldColladaSingleMesh = getParameters()->getAttributeAsBool(COLLADA_CREATE_SCENE_INSTANCES);
	getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, false);

	// read file

	while(reader->read())
	{
		readSceneNode(reader, 0, userDataSerializer);
	}

	// restore old collada parameters

	getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, oldColladaSingleMesh);

	// finish up

	reader->drop();
	return true;
}
We would only to take reuse that part of the code inside our application and change the parts in the WHILE loop to our need (refresh).

Also instead of having the readSceneNode having a VOID, it could return the node type. Would be really interesting that you expose all the functions related to the scene loading.
FuzzYspo0N
Posts: 914
Joined: Fri Aug 03, 2007 12:43 pm
Location: South Africa
Contact:

Post by FuzzYspo0N »

i like the idea Christian , it sounds like a quick and easy to implement means of controlling irr format loads.
aanderse
Posts: 155
Joined: Sun Aug 10, 2008 2:02 pm
Location: Canada

Post by aanderse »

you can't get a truly cheap scene node count given the current technology (you'd have to change the format to add a count at the top of the file i guess).

not everything you want, but this is probably the spot to start looking:

http://irrlicht.sourceforge.net/docu/cl ... c94f00ce6b

its your "loadScene_nextNode()" function.

EDIT: clarification... ISceneUserDataSerializer * userDataSerializer is what you're looking for. (posting too early in morning never end up right....)
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

aanderse, ISceneUserDataSerializer * userDataSerializer would allow me to retrieve nodes from the scene file one by one? Or get a count on the nodes elements?

One thing I was thinking was reading the file 2 times to have.
First pass: simple node count
Second pass: interpreting the node infos.

But having at least a simple way using the readSceneNode(reader, 0, userDataSerializer); would be a great step forward. We could simply update the screen with the node count at first (Also I think we could do a scene render as each node is being loaded for the one that would like to see things appear)
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

All the handling within the loading can be delegated to the userSerializer. You have a callback there which is called after every loaded node. You can choose to count the nodes, put them into user-space containers, or remove them right away. You could also render in between, since the callback is called at a stable state.
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Hummm... I will have to investigate more on how this is accomplished. I really need this to load the kind of scenes I want to make. I really don't know how to use that mecanism right now.
aanderse
Posts: 155
Joined: Sun Aug 10, 2008 2:02 pm
Location: Canada

Post by aanderse »

I don't think you actually need a node count up front if your main reason for asking these questions is speed. I probably don't understand what you really want, but a very quick example of how to use the callback I mentioned...

class NonBlockingProgressBarUpdater : public ISceneUserDataSerializer
{
GUIElement *ProgressBar;
int Count;
public:
void NonBlockingProgressBarUpdater(GUIElement *progressBar) : ProgressBar (progressBar), Count(0) {}
void OnCreateNode (ISceneNode *node)
{
Count++;
ProgressBar->animate();
ProgressBar->setText(Count + " nodes loaded so far");
}
};

now that's a real quick and dirty example, and i'm assuming you're using one of the "progress bars" that don't actually show you the percent complete, they just show a spiffy animation which tells the user "no, the application hasn't froze yet". The idea is that in the OnCreateNode function you get the scene node which has been loaded and you can actually do "stuff".

Hope that gives you at least a vague concept of what you can do with the callback - it's a really useful substitute for threading/background thread which loads resources.
Post Reply