LeSam
LeSam

Reputation: 1265

(Libgdx and Rube Box2d) merge worlds

Well well well, I use the RubeLoader to load my rube files on libgdx.

However I noticed that I can only load ONE json file

Code :

loader = new RubeSceneLoader();
scene = loader.loadScene(Gdx.files.internal("test.json"));
World mWorld ;
mWorld = scene.getWorld();

As you can see, If I want to load another json file, it will destroy the previous one because of this line :

mWorld = scene.getWorld();

So my problem is : how can I load multiple json file or how can I merge differents world into one ?

Thanks you in advance for your answers

Upvotes: 2

Views: 1258

Answers (2)

iforce2d
iforce2d

Reputation: 8272

I don't know about the libGDX loader, in the C++ version of the loader the main loading function can be easily modified to take an existing world as a parameter. If the existing world is not null, it will be used instead of making a new one. Otherwise, a new world will be created as normal.

Before (pseudocode!):

World loadWorld( File f ) {
    World w = <make a new world>
    //load the scene into w
    return w;
}

After:

World loadWorld( File f, World w ) {
    if ( w == null )
        w = <make a new world>
    //load the scene into w
    return w;
}

The same idea could probably be done in many other languages.

Upvotes: 0

noone
noone

Reputation: 19776

I checked the sourcecode of RubeLoader and libGDX and cannot see why it should break the first world. I checked it myself after that (not very extensive, but I think I covered your usecase) and it worked fine for me.

Multiple Worlds are supported by Box2D, LibGDX and the RubeLoader. But of course you need multiple instances of the World.

loader1 = new RubeSceneLoader();
scene1 = loader1.loadScene(Gdx.files.internal("XXXX.json"));
World mWorld1 = scene1.getWorld();

loader2 = new RubeSceneLoader();
scene2 = loader2.loadScene(Gdx.files.internal("ABCD.json"));
World mWorld2 = scene2.getWorld();

Now you have two Worlds and they should both work fine, but merging them wouldn't be easy at this point. Because you would have to recreate everything from mWorld2 in mWorld1 or the other way around. I'd suggest you to programmatically merge the two JSON files (libGDX has already the necessary JSON tools, but you might use other small json libraries like Jackson) and then load this merged scene. That should be a lot easier than merging two Worlds.

Edit: If you need to merge the Worlds not right from the start, but after a while, the easiest would be to modify the RubeWorldSerializer. Specifically this part:

World world = new World(gravity, allowSleep);
world.setAutoClearForces(autoClearForces);
world.setContinuousPhysics(continuousPhysics);
world.setWarmStarting(warmStarting);

Try to find a way to input your already existing mWorld1 here instead and when loading the second scene, all Bodies and Joints should automatically be added to this World, instead of a completely new one.

Edit2: A quick idea how it could be done:

Add this to the RubeWorldSerializer: public static World mergeWorld;.

Change the World initialization like this:

World world;
if (RubeWorldSerializer.mergeWorld == null) {
    world = new World(gravity, allowSleep);
    world.setAutoClearForces(autoClearForces);
    world.setContinuousPhysics(continuousPhysics);
    world.setWarmStarting(warmStarting);
} else {
    world = RubeWorldSerializer.mergeWorld;
}

Now Your loading would have to look like this:

loader1 = new RubeSceneLoader();
scene1 = loader1.loadScene(Gdx.files.internal("XXXX.json"));
World mWorld1 = scene1.getWorld();

RubeWorldSerializer.mergeWorld = mWorld1; // this is important in between your loading.

loader2 = new RubeSceneLoader();
scene2 = loader2.loadScene(Gdx.files.internal("ABCD.json"));
World mWorld2 = scene2.getWorld(); // in theory mWorld2 should be the same like mWorld1 now, and it should be both worlds merged

Upvotes: 3

Related Questions