WebXR, KeepAssets and AssetContainers

Hi,

hopefully a quick question. I am looking at refactoring my project to use AssetContainers rather than multiple scenes, to allow easier transition when in WebXR (ie allow triggering from non-user interaction)

From what I can see there is no way to create an asset directly into a container but you must first add it to the scene then move it to the container
container.moveAllFromScene(keepAssets);
…which removes it from the scene… so you then add it back in…
container.addAllToScene();
That’s all fine.

But it looks like to me that if I create a default webXR experience this will add a few things to the scene, which is dependent on the users hardware. But I need to add everything that the webXR experience has added to the keepAssets so it doesn’t end up in the AssetContainer. Essentially I want a loading scene that just has all the webXR stuff and then I will add and remove containers to it.
But there doesn’t seem to be an equivalent way to add all the assets currently in the scene to keepAssets. Is there an easy way to do this that I am missing or do you have to iterate over assets and manually add them to the appropriate part of keepAssets?

Hey @MarkM ,

I assume you are referring to the assets created when the WebXR features are initialized. These are the only assets that you might need to recreate. Not that simple, as those assets are created and usually referenced in the features themselves.
I would recommend not to initialize the features before you actually need them. This way they are created only when needed and can be disposed when no longer needed. For example, don’t auto-init the teleportation feature (which creates the teleportation ring when initialized). Add the feature only when needed and when you are sure you are in the right scene.

Hey @RaananW ,
yes things added by the features but also the controllers, impostors and camera.
These are all added as root nodes, it might make it easier if they were added as a child of a root node positioned at the origin (say called webXR_root). Is that possible?
I am not sure if KeepAssets applies to the hierarchy (inc children) but it would make the scene tree cleaner anyway, not sure if there was a reason it was done that way or not, eg impostors.

Just wondering if you have a comment on this @RaananW ?
I have been pulled off onto another (non-BJS) project so haven’t looked at this for a while…just using a quiet time to come back in to visit the community and get a fix :slight_smile:

Hi @MarkM,

Sure, I’m not going to say it doesn’t make sense :slight_smile:
Having a single Node that is the root of all WebXR-related nodes makes sense, but might have different issues related to it. If you want to create an issue on github (as a feature request) it will be great. I’ll make sure it doesn’t cause any unwanted side effects. Hope this helps!

1 Like

Thanks as always @RaananW
I will add the feature request on github.

1 Like

Issue for follow up: Parent node for all created WebXR nodes · Issue #11672 · BabylonJS/Babylon.js · GitHub

2 Likes

Finally trying to get back to this. I am attempting to refactor my code to use Asset Containers and work around this for the timebeing, I think I have found an oversight in the AssetContainer implementation.

My Particle Systems were not getting handled correctly and when I dug into the code for Asset Containers they do not do anything with particle systems. I have to manually add/remove them. Is there a reason for this, some other limitation perhaps?

It seems to work if I do something like (but I haven’t fully tested yet)

                    container.addAllToScene();
                    container.particleSystems.forEach( function(p) {
                        container.scene.addParticleSystem(p);
                    });

and

                    container.removeAllFromScene();
                    container.particleSystems.forEach( function(p) {
                        container.scene.removeParticleSystem(p);
                    });

any other gotchas like this with Asset Containers?

Yeah, if we are already handling many other types of assets, we should also do that to particle systems, I totally agree. Not sure if it will go in to the final 5.0.0 release but it would be great if you can create a github issue for us to follow! Link this discussion in your description

Thanks!

Done. Issue added at

1 Like

I have run into another problem when using AssetContainers to effectively switch scenes in WebXR.

In the Start Scene I setup a physics plugin and then in the “normal” scenes I add assets and move them off to the Asset Containers. This is all working well but the physics Impostors remain active when I removeAllFromScene, leading to all sorts of weird reactions. I have verified in the console that scene.getPhysicsEngine()?.getImpostors() returns an array of impostors from the previous scene where the assets they are imposting have been removed.

Is there a way I can remove impostors (or disable them) if the asset is no longer in the scene?
If I go back to the first scene then I want the impostors to again be active (but not those added in scene 2)

This sounds like a similar problem to the particle systems issue. Maybe whoever fixes the particle systems issue can also tackle this one. @RaananW What do you think?

I was hoping it was going to be as simple as keeping an array of impostors added then iterating them doing a scene.getPhysicsEngine().removeImpostor (and addImpostor to reinstate them) but this just throws up errors in the plugin (i am using ammo so sleep is not available)

Impostors are connected to an external engine (your physics engine), and will need to be recreated every time you add to scene. We can’t serialize the physics engine’s data and expect it to work afterwards.

It’s a bit more than the particle system issue. But it does need to be addressed, i agree. When taken out of the scene, the physics impostors must be disposed. When brought back to the scene, the physics impostors need to be recreated. Will be interesting to see how we can automate this :slight_smile: Especially the part where we recreate the impostor. disposing is not an issue.

I would appreciate a github issue for this one, if possible. Linking this conversation (and this comment). We can tackle this. I would define not disposing the impostors when removed from the scene as a bug. But recreating is a new feature that needs to be well planned.

Ok, I will add some GitHub issues.

I was a bit stressed about this as it became a show stopper, anyway I have found a solution that works for my situation. It is a bit hacky but seems to get the job done. I also tried switching to Cannon as it has sleep and wakeUp implemented and that did work but introduced many more issues…and I was using soft bodies as well that are not in Cannon. Anyway, I waffle, I dug into the code for Ammo and the AmmoJSPlugin and found a way to effectively sleep the physicsBody in Ammo.

My solution is to toggle a flag which disables collisions, I have a class that derives from AssetContainer and when I load my assets I execute this code:

          this.meshes.forEach( m => {
                if (m.physicsImpostor?.physicsBody)
                m.physicsImpostor.physicsBody.setCollisionFlags(m.physicsImpostor.physicsBody.getCollisionFlags() & ~AmmoJSPlugin.DISABLE_COLLISION_FLAG);
            });

and when I unload the assets I execute this:

            this.meshes.forEach( m => {
                if (m.physicsImpostor?.physicsBody)
                    m.physicsImpostor.physicsBody.setCollisionFlags(m.physicsImpostor.physicsBody.getCollisionFlags() | AmmoJSPlugin.DISABLE_COLLISION_FLAG);
            });
1 Like

Hello @MarkM just checking in if you’d like any further assistance :smiley:

Hi @carolhmj
thanks for checking. I think I am ok for the present.

I haven’t been able to do any more on this just yet though, but with the change I made in the last post it is essentially working, with the exception of when I switch scenes (ie unloading and loading containers and setting some things like gravity in callbacks) the physicsBodies were not refreshing with the gravity of the scene, ie if I loaded a scene with zero gravity then went back to a scene with gravity then all bodies would be floating until I nudged them and then they fall.

I keep getting called onto other non-BJS projects and only have a few weeks left on my contract so I am not sure I will get to finish it. It may become a labour of love. In addition, I live on a boat on the Brisbane river (in Aust) and we have just had a major flooding event with a lot of upheaval/damage so I am rather pre-occupied…but hope to get back to it. :slight_smile:

1 Like

cc @Raggar . Sleeping ammo!

@MarkM hope you ll be all safe and getting better soon :frowning: