Writing 3D Models out to Disk

Panda has two native file formats for models.

Egg files (with the extension .egg) are written in an ASCII human readable format. The egg format is designed to be easy to read and modify if necessary, and easy to write a convert into from another third-party format. Also, the egg format is intended to be backward-compatible from all future versions of Panda3D, so if you have an egg file that Panda can load now, it should always be able to load that file. (Well, we can’t really make guarantees, but this is what we shoot for.) See Parsing and Generating Egg Files for more information about the egg format.

BAM Files

Because of the way the egg syntax is designed, an egg file might be very large, sometimes many times larger than the file it was converted from. It can also sometimes take several seconds for Panda to load a large egg file.

Bam files (with the extension .bam), on the other hand, are binary files that are more closely tied to a particular version of Panda3D. The bam format is designed to be as similar as possible to the actual Panda data structures, so that a bam file is relatively small and can be loaded very quickly. However, you should not consider the bam file format to be a good long-term storage format for your models, since a future version of Panda3D may not be able to load bam files from older versions. (That said, we have been pretty good at retaining backward compatibility for .bam files anyway, so you may find it possible to ignore this advice, albeit at your peril.)

You can always convert egg files to bam files using the program egg2bam. For many simple models, it is also possible to convert back again with the program bam2egg, but you should not rely on this, since it does not convert advanced features like animation; and some structure of the original egg file may be lost in the conversion.

You can load files of these formats, as well as any other supported format, using the loader.loadModel interface. Any file types other than .bam or .egg will be automatically converted at runtime, exactly as if you had run the appropriate command-line conversion tool first.

The Bam Interface

The easiest way to save geometry is to use to call writeBamFile(filename) from the NodePath that contains your geometry.

myPanda = loader.loadModel("panda")

# do some fancy calculations on the normals, or texture coordinates that you
# dont want to do at runtime

# Save your new custom Panda
myPanda.writeBamFile("customPanda.bam")

The Egg Interface

One easy way to create .egg file for geometry that has already been made is to create a .bam file and use bam2egg. However, you will often want to use the egg interface to create geometry in the first place; this is usually the easiest way to create geometry in Panda3D.

The complete documentation for using the egg interfaces has yet to be written, but the egg library is really quite simple to use. The basic idea is that you create an EggData, and an EggVertexPool to hold your vertices; and then you can create a series of EggVertex and EggPolygon objects. If you want to create some structure in your egg file, you can create one or more EggGroups to separate the polygons into different groups. Here is an example:

from panda3d.core import Point3D, deg2Rad, NodePath, Filename, CSZupRight
from panda3d.egg import EggPolygon, EggVertexPool, EggData, EggVertex, loadEggData, EggCoordinateSystem
import math

...

def makeWedge(angleDegrees = 360, numSteps = 16):

    z_up = EggCoordinateSystem()
    z_up.setValue(CSZupRight)

    data = EggData()
    data.addChild(z_up)

    vp = EggVertexPool('fan')
    data.addChild(vp)

    poly = EggPolygon()
    data.addChild(poly)

    v = EggVertex()
    v.setPos(Point3D(0, 0, 0))
    poly.addVertex(vp.addVertex(v))

    angleRadians = deg2Rad(angleDegrees)

    for i in range(numSteps + 1):
        a = angleRadians * i / numSteps
        y = math.sin(a)
        x = math.cos(a)

        v = EggVertex()
        v.setPos(Point3D(x, 0, y))
        poly.addVertex(vp.addVertex(v))

    return data
...

# Creating egg data
data = makeWedge()

# To write the egg file to disk, use this:
data.writeEgg(Filename("wedge.egg"))

# To load the egg file and render it immediately, use this:
model = NodePath(loadEggData(data))
model.reparentTo(render)

See the generated API documentation of panda3d.egg for more complete information about the egg library.