Async world loading


photo

Recommended Posts

Is it possible to load world asynchronously?

I want to have one world active and running, while another loading. Then switch active world.

Link to post

Hmmm... maybe there is a way to mimic that?

Is it possible to have several worlds?

If so, what if put all world content into NodeLayer. And then load it async(I saw in doc, that async node loading is supported) to non-active world.

And then somehow switch active world. [By the way, only one world is "active", isn't?]

 

Or as alternative (ignoring world logic), what if just async load NodeLayer and then disable active, and enable loaded. Will there ... glitches, if these NodeLayer's geometrically intersects?

Link to post

Yes, only a single .world file can be loaded at once.

Often you can see that hidden areas are used to emulate the seamless transitions between the different locations (just place them far apart between each other) and when you need to switch the scene you can simply move camera to the desired position. To make sure that everything is loaded you can additionally create a viewport (that would not be shown on screen) and render some frames to trigger files loading.

In depends on the use-case, so you can try to experiment with the different ones and choose that would fit your needs. Maybe Switcher node can be useful in some way as well: https://developer.unigine.com/en/docs/2.13/objects/worlds/world_switcher/?words=switcher#highlight

Thanks!

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post

For anyone solving the same problem.

Basically, world consists from two parts: data(nodes) and logic.

It is possible to async-load and keep as many as needed worlds with Unigine. You just have to put your world into nodelayer/dummynode. You can async load that node later. As soon as your node async load finish (AsyncQueue::takeNode return not null) - setEnabled(false) to it. When you will ready to actually change the world - enable loaded world, and delete current (or disable, if you need it latter).

The following snippet switch between 2 worlds/layers:

int AppSystemLogic::update()
{
	// Write here code to be called before updating each render frame.	
	if (App::clearKeyState(App::KEY_PGUP))
	{
		Log::message("UP");
		if (active_node_layer == 1) {
			node_load_id = AsyncQueue::loadNode("world_layer2.node");
		}
		else {
			node_load_id = AsyncQueue::loadNode("world_layer1.node");
		}
	}

	if (node_load_id >= 0) {
		node = AsyncQueue::takeNode(node_load_id);		
		if (node) {

			// disable active
			{
				NodePtr active_node;
				if (active_node_layer == 1) {
					active_node = World::getNodeByName("NodeLayer1");
					active_node_layer = 2;
				} else {
					active_node = World::getNodeByName("NodeLayer2");
					active_node_layer = 1;
				}
				active_node->deleteLater();
				/*active_node->setEnabled(false);
				active_node->updateEnabled();*/
			}

			node->setEnabled(true);
			node->updateEnabled();
			node_load_id = -1;
		}
		else {
			Log::message("Loading/n");
		}
	}

	return 1;
}

 

As for world logic - https://developer.unigine.com/en/docs/2.13/code/usage/multiple_worldlogic/index

Link to post