Write Bam File to Disk and load it again - help

I need your help:

self.render.write_bam_file("...")

When writing this, you save the self.render Node, aswell everything parented to it as .bam file. But when loading it in again, you have 2 render-Nodes (The one of the current Panda3D Instance and the one saved inside the .bam file).

In my case, the nodes parented to the render node, aren’t visible. I think that 2 render Nodes can’t work, even when one is parented to the other.

My target is, to create a level Editor, that can export a scene as .bam file, and also load it in again

Here you can see the self.render.ls() function:

Works (Cube visible):

PandaNode render S:(CullFaceAttrib RescaleNormalAttrib)
  ModelRoot cube.egg
      GeomNode Cube (1 geoms: S:(MaterialAttrib))

Doesn’t work (Cube invisible):

PandaNode render S:(CullFaceAttrib RescaleNormalAttrib)
  PandaNode render S:(CullFaceAttrib RescaleNormalAttrib)
    ModelRoot cube.egg
      GeomNode Cube (1 geoms: S:(MaterialAttrib))

My question:
To avoid this, I need to save only the children of the render node, but not the render node itself.
Also I tried to create a empty Node called “ROOT” and parent everything to it, and then save it from there:

self.root.write_bam_file(...)

But that also doesn’t work, and the other nodes (models & actors) aren’t visible, when loaded in.

So I just want to export the children of the render node, but not the render node itself…
Does someone know how to do this, or has a better solution?

Ps: Somehow the Cube appears in Pview

Have you tried?

Node.reparentTo(render)

while loading.

Yes, I loaded the .bam file and reparented to the render node. So it looked like this:

PandaNode render S:(CullFaceAttrib RescaleNormalAttrib)
  PandaNode ROOT
    ModelRoot cube.egg
      GeomNode Cube (1 geoms: S:(MaterialAttrib))

But unfortunately, that doesn’t work, and the Cube stays invisble
But thank you for your answer :slight_smile:

For example, you need to start the editor - create a bam file. Then start the game. All works.
demo.7z (500 Bytes)

I took your example and modified it a bit. The Editor reopens, and resaves the .bam file.
This is how an Editor works: Create & Save Level; Reopen and edit and save; Then it’s ported to game
For more view the file…
demo_mod.rar (1.01 KB)

Can not open the file as an archive.

Ok I compressed it with 7-Zip:
demo_mod.7z (769 Bytes)

Use find() to take all the nodes of the root.

Decision:

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  

from panda3d.core import NodePath

from direct.showbase.ShowBase import ShowBase
 
import os
class Game(ShowBase):  
   def __init__(self):  
        ShowBase.__init__(self)

        #CREATES LEVEL
        root = NodePath("level")
        root.reparentTo(render)
        
        level = loader.loadModel("box")
        level.reparentTo(root)
        
        root.write_bam_file("MyLevel.bam")

        #CLEAR AND THEN LOAD AGAIN
        for child in root.getChildren():
            child.removeNode()
            
        del level

        #LEVEL LOADS ANS SAVES AGAIN
        file = loader.loadModel("MyLevel.bam")
        level = file.find('*') 
        level.reparentTo(root)

        root.write_bam_file("MyLevel.bam")
        
        ##LIST THE SCENE GRAPH OF THE MODEL
        loader.loadModel("MyLevel.bam").ls()


game = Game()  
game.run()

I came to a much more efficient and easy solution:

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  

from panda3d.core import NodePath

from direct.showbase.ShowBase import ShowBase
 
import os
class Game(ShowBase):  
   def __init__(self):  
        
        ShowBase.__init__(self)
        
        level = loader.loadModel("box")
        level.reparentTo(render)
        
        render.write_bam_file("MyLevel.bam")
        #LEVEL LOADS ANS SAVES AGAIN
        level = loader.loadModel("MyLevel.bam")
        render.write_bam_file("MyLevel.bam")
        
        ##LIST THE SCENE GRAPH OF THE MODEL
        loader.loadModel("MyLevel.bam").ls()


game = Game()  
game.run()

I’m just thinking to abstract. There’s no need to clear the scene graph! You can just reload the level-model!

I generally do not recommend using the egg file to describe the level. It is better to create a textual description of the level. It’s easy to modify and stuff.

You could do something like this:

render.writeBamFile('test.bam')

loadedRender = loader.loadModel('test.bam')
render.node().stealChildren(loadedRender)