Map format - egg vs xml

I thought I’d post here and see what kind of feedback or suggestions I get.

I’ve been doing some egg export tests with Maya, Max and Blender just to expose myself to these systems in addition to reading up on the threads regarding standalone map editors and map formats. It seems like some people have solved the problem of map format by exporting an egg which contains empties, then parsing the egg file on the app side to turn these empties into node paths.

I’ve looked at using this approach mainly in conjunction with Maya and found it somewhat limiting when it comes to exporting anything but transforms with preset tags. As far as I’m aware the egg exporter only recognizes information tagged on an object if the data type is enum, and this approach isn’t a great solution when trying to export things like lights as these tend to have attributes with arbitrary float values. You also have to update your map loader on the game side to match every tag to the correct model.

Other people have attempted to solve this issue by building a generic map editor. One of my biggest concerns with an approach like this is that is seems like you have to write another program before you can start your project - something which I personally feel is a considerable obstacle. After all, if most of the functionality is there in your 3D app of choice, why reinvent it?

Anyway, enough ranting :smiley: I thought it would be neat to have an xml based map format that could be generated from either Maya, Blender or Max. Maya and Max have the ability to create references (ref / xref) and Blender looks like it might too (linking / proxy?) which gives you a model in the scene to manipulate and a file path to find the model. We then have a Python script to interface with the different apps to pick up transforms of references, lights, sounds, properties, etc and parse an xml map. This then gets built on the game side with a map parsing class.

For example a map xml might look like this:

<Map>
    <NodePath filePath="box.egg" x="0 1 0" y="1 0 0" z="0 0 1" t="2 0 0" />
    <NodePath filePath="smiley.egg" x="1 0 0" y="0 1 0" z="0 0 1" t="-1 0 0" />
</Map>

and you would load it like this:

import xml.etree.cElementTree as et

from direct.showbase.ShowBase import ShowBase
from pandac.PandaModules import Filename, TransformState, Mat4, Mat3


class MapLoader( object ):
    
    """A class to load map files into Panda3D."""
    
    def __init__( self, filePath ):
        tree = et.parse( filePath )
        self.ProcessElement( tree.getroot() )
        
    def __GetMat( self, element ):
        
        """Return a matrix4 built up from x, y, z and t attributes."""
        
        def __GetFloat3( string ):
            
            # Return a tuple of three floats that were delineated by a space
            floats = string.split( ' ' )
            return (float( floats[0] ), float( floats[1] ), float( floats[2] )) 
        
        mat = Mat4()
        mat.setRow( 0, __GetFloat3( element.get( 'x' ) ) )
        mat.setRow( 1, __GetFloat3( element.get( 'y' ) ) )
        mat.setRow( 2, __GetFloat3( element.get( 'z' ) ) )
        mat.setRow( 3, __GetFloat3( element.get( 't' ) ) )
        return mat
        
    def ProcessElement( self, element ):
        
        """Build an element from xml."""
        
        # Process node paths
        if ( element.tag == 'NodePath' ):
            
            # If the node path has a filePath attribute, load the model from
            # that location
            filePath = Filename.fromOsSpecific( element.get( 'filePath' ) )
            model = loader.loadModel( filePath )
            model.reparentTo( render )
            
            # Set the model's transform
            model.setMat( self.__GetMat( element ) )
        
        # Recurse down the tree
        for childElement in element:
            self.ProcessElement( childElement )
    

base = ShowBase()
mapLoader = MapLoader( 'map.xml' )
base.run()

Is this something that could be useful, or have I complete missed some of the functionality that using only eggs provides?

I’d appreciate any input!

There is common tools to deal with egg format while there is none to deal with your-level-xml format. “XML” is not a 3d format like egg is its just an encoding for one. But really it does not matter to us do what works best for you.