Jump to content

How can I load a world located in arbitrary folder?


photo

Recommended Posts

Hi

 

I used following C++ codes to load a scene, and it worked perfectly.

	Console* pConsole = Console::get();
	pConsole->run("world_load ../data/UnigineScene/UnigineScene");

Then I renamed the "data" folder to "data_1", and modified the C++ codes like this:    

	Console* pConsole = Console::get();
	pConsole->run("world_load ../data_1/UnigineScene/UnigineScene");

Unfortunately, It failed.

 

I guess the problem is related with something about "Unigine File System", I try to add:

FileSystem::addDirectory("../data_1");

before world_load, but It dosen't work.

 

Please give me some suggestions, Thanks.

Link to comment

Hi Silent,

 

I try to call filesystem_reload a while ago:

Console* pConsole = Console::get();
pConsole->run("filesystem_reload ../data_1");//call filesystem_reload in advance
pConsole->run("world_load ../data_1/Scene_1/Scene_1");

but It doesn't work.

 

Interestingly, After I called the filesystem_reload command, I still can load the world in the default directory successfully.

Console* pConsole = Console::get();
pConsole->run("filesystem_reload ../data_1");//call filesystem_reload in advance
pConsole->run("world_load ../data/Scene/Scene");//--data-- is the default directory. Interestingly, It succeeded. 

It seems the filesystem_reload command is malfunction.

I used absolute directories and try it again. Unfortunately, I got an exactly same outcome.

Link to comment

Hi Silent,

 

1> Please put my "Players.cpp" file into "starter_windows_2.4.1\source\samples\Api\Nodes\Players" folder to overwrite the old one. meanwhile,  Please replace my "data" folder with the original one as will.

class AppSystemLogic : public SystemLogic
{
public:
	AppSystemLogic() {}
	virtual ~AppSystemLogic() {}
	virtual int init()
	{
		App::get()->setUpdate(1);
		
		Console* pConsole = Console::get();
 		//load a world from default directory, everything is OK. 
		pConsole->run("world_load data/unigineEng/unigineEng");
 		return 1;
	}
};

2> then rename the folder from "data" to "data_Eng".

class AppSystemLogic : public SystemLogic
{
public:
	AppSystemLogic() {}
	virtual ~AppSystemLogic() {}
	virtual int init()
	{
		App::get()->setUpdate(1);
		
		Console* pConsole = Console::get();
		//but after you renamed the "data" to "data_Eng", than run it again, It dose not work well. 			
                pConsole->run("filesystem_reload data_Eng");
		pConsole->run("world_load data_Eng/unigineEng/unigineEng");
		return 1;
	}
};
Link to comment

Hi Lin,

I hope renaming the data catalog while the engine is running is not what you want because I'm not sure whether we could manage to get it working. :)

You can choose any name and any place for your data catalog as long as you don't forget to provide the engine with the command line argument "-data_path" to point to that catalog.
You can provide multiple data catalogs actually.
I think that's what you forgot to do after you had renamed you "data/" - to go to project settings and fix engine startup arguments.

I noticed also that you use extra path components when referring to the world file.
Once you provided the engine with the correct path to data catalog you can, and normally should, refer to files inside it with relative names.

Imagine I have the world file "D:\Unigine\my_game\data\worlds\tier_0.world".
I run engine using the following comand: "my_game.exe -data_path D:\Unigine\my_game\data\".
Now I refer to this world by name "worlds/tier_0", for example opening it via console: "world_load worlds/tier_0".

 

Also, loading the world file lying outside the data catalog is possible but is not a good idea.

So I hope this is not what you want too. :)

Link to comment

Hi Ded,

 

Thanks for your reply.

 

I'm not trying to rename a data catalog while the engine is running. 

 

Actually, My demand is quite simple.

Say, I have already had two content folders -- one named "data_tier_0" the other one named "data_tier_1". 

I run engine using the following comand: "my_game.exe -data_path D:\Unigine\my_game\data_tier_0\". everything is perfect. My question is "How can I reload the other world referring to data_tier_1 using C++ APIs just in the same .exe which is running, rather than shutdown this .exe and restart it again using data_tier_1 as command line argument".

Link to comment

Hi Lin,

 

You can pass multiple data_path's on engine startup:: -data_path <1> -data_path <2>. You also can keep inside single data directory two different folders with your content: 

  • D:\Unigine\my_game\data\data_tier_0
  • D:\Unigine\my_game|data\data_tier_1

Thanks!

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

Link to comment

Hi Silent,

 

As I've mentioned that my application allows user to open a new scene in anytime. I can't predict which data path will be opened in advance, so I'd like to figure out a way to reload a new scene after my application has been running.

In my point of view, as a general application, "Close a file" then "Open an other one" are kind of normal functions, so I'd like to carry them out.

 

Thanks! 

Link to comment

If we're talking about one simple .world file and all the content it may reference is lying in our initial data path, then you can load it using the absolute path.

 

But I bet you want to load an entire project, with nodes and meshes and textures, from an arbitrary path without reloading the engine.

Try the following code:

Unigine::FileSystem::addDirectory("<arbitrary_path>");
Unigine::Console::get()->run("filesystem_reload");
Unigine::Console::get()->flush();
Unigine::Console::get()->run("world_load <world_name>");

This is somewhat a hack, the engine was not designed to support such workflow.

Hope it'll work for you!

Link to comment

Hi Ded.

Great! your solution works. Thank you.

But I bet you want to load an entire project, with nodes and meshes and textures, from an arbitrary path without reloading the engine.

Just like you mentioned, that is what I exactly want to do.

Furthermore, I'd like to know a bit more insides.
1> I consider I should release the resource associated with the previous one, before I reload a new world, So I guess the code should be like this:

Unigine::Console::get()->run("world_clear");
Unigine::Console::get()->run("filesystem_clear ");
Unigine::FileSystem::removeDirectory("");//I didn't find any API like this, maybe it's not necessary

Is my assume right?

 

2>If I use the strategy Silent told me: 

 

You can pass multiple data_path's on engine startup:: -data_path <1> -data_path <2>. You also can keep inside single data directory two different folders with your content: 

  • D:\Unigine\my_game\data\data_tier_0
  • D:\Unigine\my_game\data\data_tier_1

I mean the path includes numerous contents, then what kind of consumptions It will cause? Where are the comsumptions? in system memory or GPU memory or harddisk cache files? 

 

3> I'm a bit confused.

Unigine::FileSystem::addDirectory("<arbitrary_path>");
Unigine::Console::get()->run("filesystem_reload");
Unigine::Console::get()->flush();
Unigine::Console::get()->run("world_load <world_name>");

 

This is somewhat a hack, the engine was not designed to support such workflow.

If the workflow you mentioned is not recommended, then what cases do those APIs (addDirectory, filesystem_reload etc.)work for?

Link to comment

Hi Lin,

One of the responsibilities of the engine filesystem is to manage an index that maps virtual file names to their real paths.
Something like:

"textures/lut.dds" -> "D:\Unigine\my_game\data\textures\lut.dds"
"meshes/characters/andy.mesh" -> "D:\Unigine\my_game\data\meshes\characters\andy.mesh"
"core/unigine.cpp" -> "D:\Unigine\my_game\data\core.ung@unigine.cpp"

This index is pretty lightweight and it takes really a LOT of files for it to consume some noticeable amount of memory.
Also, It has no impact on a GPU memory consumption at all.

The engine creates this index once at startup and doesn't keep track of any changes inside managed data paths.
If you remove or create a file using the engine API, the engine, of course, will update the index.
But when, for example, your application uses another process to generate some content, the engine won't know about it.
That's for there is "filesystem_reload" command, it forces the engine filesystem to re-create the index on demand.

Unigine::FileSystem::addDirectory method is actually should be called before the engine even initialized.
It's an alternative for passing additional "-data_path" argument to the application.
Your main() may look like:

int main(int argc, char **argv)
{
	Unigine::FileSystem::addDirectory("D:\\Unigine\\common\\");
	EnginePtr engine(UNIGINE_VERSION, argc, argv);
	AppSystemLogic system_logic;
	AppWorldLogic world_logic;
	AppEditorLogic editor_logic;
	engine->main(&system_logic, &world_logic, &editor_logic);
	return 0;
}

The data path set is not intended to be modified during the application lifetime, that's why there is no "removeDirectory" method.
And that's why I said it's a hack. :)

I forgot to mention that there's also a risk of running into a name conflict when you add another data path with an unknown content in it.

Consider the following idea.
When your user wants to open another project from an arbitrary path, your application can run another engine instance with the corresponding arguments.
This, however, may require some elaborate inter-process communication code and make the architecture more complicated. :(

Link to comment

Hi Ded,

 

Thank you very much.

 

When your user wants to open another project from an arbitrary path, your application can run another engine instance with the corresponding arguments.

This, however, may require some elaborate inter-process communication code and make the architecture more complicated. :(

I can't agree you more. 

 

So if there is a  method like "removeDirectory" or "removeAllDirectories" indeed, then I wouldn't take any risks with name conflicts at all, and the workflow given above wouldn't be a hack any more.

To Unigine, I'm not sure It's possible or not. but It makes sense for me :) 

Link to comment
×
×
  • Create New...