Import.py :  » Game-2D-3D » PyRA2 » PyRA2-0.1.1 » lib » PyRA2 » GMIModel » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Game 2D 3D » PyRA2 
PyRA2 » PyRA2 0.1.1 » lib » PyRA2 » GMIModel » Import.py
# PyRA2: Python support for Robot Arena 2 file formats.
# Copyright (C) 2003  Martijn Pieters <pyra2@zopatista.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

"""GMI (.gmf) model import

The loadScene utility method will import a complete scene from the
filedescriptor passed in.

"""

from struct import unpack
from os.path import dirname

class ImportException(Exception):
    """Raised when finding inconsitencies in the imported file"""

def loadScene(fd):
    """Load a GMI 3D scene from filedescriptor."""

    if hasattr(fd, 'name'):
        dir = dirname(fd.name)
    else:
        dir = ''
    importer = SceneImporter(fd, dir)
    return importer.loadScene()

#
# Generic binary file reader
#
class BinaryImporter:
    _fd = None
    _last = None
    
    def __init__(self, fd):
        self._fd = fd

    def _read(self, len):
        self._last = self._fd.read(len)
        return self._last

    def readInt(self):
        """Read an integer"""
        return unpack('i', self._read(4))[0]

    def readFloat(self):
        """Read a float"""
        return unpack('f', self._read(4))[0]

    def readString(self):
        """Read a string"""
        length = self.readInt()
        value = self._read(length)
        if length > 0:
            value = value[:-1] # Strip off NULL, serves no purpose in Python
        return value

    def readByte(self):
        """Read unsigned int byte"""
        return unpack('B', self._read(1))[0]
    readBoolean = readByte

    def readColor(self):
        """Read a 4 byte RGB color

        Return as 0.0-1.0 float RGB values. Note: values stored in bgr order.

        """
        rgb = list(unpack('BBBx', self._read(4)))
        return tuple([c/255.0 for c in rgb])

    def readFloatTriple(self):
        """Read a 3 float values"""
        return unpack('fff', self._read(12))
    readVector = readFloatTriple
    readPoint = readVector

    def readIndexSet(self):
        """Read a 3-int index set"""
        return unpack('iii', self._read(12))
    readTriplet = readIndexSet

    def readTM(self):
        """Read a 3x4 transformation matrix"""
        return (self.readFloatTriple(), self.readFloatTriple(),
                self.readFloatTriple(), self.readFloatTriple())

    def _err(self, msg):
        """Convenience method for generating error messages."""
        try:
            filename = self._fd.name
        except AttributeError:
            filename = repr(self._fd)
        return "%s (file %r, pos %i, last read %r)" % (
            msg, filename, self._fd.tell(), self._last)

#
# Import a complete scene
#
class SceneImporter(BinaryImporter):
    """GMI Scene importer"""
    _scene = None
    
    def __init__(self, fd, dirname):
        from Scene import Scene
        BinaryImporter.__init__(self, fd)
        self.readHeader()
        self._scene = Scene()
        self._scene._path = dirname

    def loadScene(self):
        """Import complete scene"""

        self.readScene()
        self.readMaterialList()
        self.readObjectList()

        if self._read(1) != '':
            raise ImportException, self._err("We didn't parse the whole file")

        return self._scene

    def readHeader(self):
        """Read the initial header.

        Raises ValueError if file is not recognized as a GMI file.

        """
        self._fd.seek(0)
        magic = self._read(3)
        if magic != 'GMI':
            self._fd.seek(0)
            raise ValueError('Not a GMI file!')
        
        err = 'Unexpected header data'
        assert self.readInt() == 3, self._err(err) # Version
        assert self.readInt() == 1, self._err(err) # Model type (Basic)
        assert self.readInt() == 0, self._err(err) # ??
        assert self.readInt() == 15, self._err(err) # ??

    def readScene(self):
        """Read all data from the scene node"""
        id, flags, length = self.readTriplet()
        start = self._fd.tell()
        assert id == 1, self._err('Expected Scene node')
        assert flags == 2, self._err('Scene node flags not 2')

        self._scene._source = self.readString()
        self._scene._firstframe = self.readInt()
        self._scene._lastframe = self.readInt()
        self._scene._speed = self.readInt()
        self._scene._ticks = self.readInt()
        self._scene._static_bg = self.readColor()
        self._scene._static_ambient = self.readColor()

        # Make sure we finished reading the section
        assert self._fd.tell() == start + length, self._err(
            'Unexpected Scene Node length mismatch')

    def readMaterialList(self):
        """Read the material list section"""
        importer = MaterialListImporter(self._fd, self._scene._materials)
        importer.readMaterialList()

    def readObjectList(self):
        """Read the object list section"""
        importer = ObjectListImporter(self._fd, self._scene._objects)
        importer.readObjectList()

#
# Import Material List node
#
class MaterialListImporter(BinaryImporter):
    _materialList = None

    def __init__(self, fd, materialList):
        BinaryImporter.__init__(self, fd)
        self._materialList = materialList

    def readMaterialList(self, sizehint=None):
        """Read the material list section"""
        id, flags, length = self.readTriplet()
        start = self._fd.tell()
        assert id == 7, self._err('Expected Material List node')
        assert flags == 2, self._err('Material List node flags not 2')

        count = self.readInt()
        if sizehint is not None:
            assert count == sizehint, self._err(
                "Size hint didn't match actual count")

        for i in range(count):
            importer = MaterialImporter(self._fd)
            importer.readMaterial(self._materialList, i)

        assert self._fd.tell() == start + length, self._err(
            'Unexpected Material List node length mismatch')

#
# Material Node
#
class MaterialImporter(BinaryImporter):
    def readMaterial(self, materialList, index):
        id, flags, length = self.readTriplet()
        start = self._fd.tell()
        assert id == 8, self._err('Expected Material node')
        assert flags == 2, self._err('Material node flags not 2')

        ref_no = self.readInt()
        assert ref_no == index, self._err(
            'Material reference number out of sync?')

        name = self.readString()
        klass = self.readString()

        material = materialList._createMaterial(klass)
        material._name = name

        material._ambient = self.readColor()
        material._diffuse = self.readColor()
        material._specular = self.readColor()

        material._shine = self.readFloat()
        material._shine_str = self.readFloat()
        material._trans = self.readFloat()
        material._wire = self.readFloat()
        material._shading = self.readInt()
        material._xp_falloff = self.readFloat()
        material._self_illum = self.readFloat()

        # It may be that the 4 bytes for two-sided are actually two 2 byte
        # fields; one for two-sided, one for falloff; I have yet to come across
        # an example though. It is certain that the first byte at the very
        # least pertains to two-sided-ness.
        material._two_sided = self.readInt()
        material._falloff = 0

        material._xp_type = self.readInt()

        texture_count = self.readInt()
        if texture_count:
            assert klass == 'Standard'
            importer = TextureListImporter(self._fd, material._textures)
            importer.readTextureList(texture_count)

        sub_count = self.readInt()
        if sub_count:
            assert klass == 'Multi/Sub-Object'
            importer = MaterialListImporter(self._fd, material._sub_materials)
            importer.readMaterialList(sub_count)

        assert self._fd.tell() == start + length, self._err(
            'Unexpected Material node length mismatch')
        

#
# Import Texture List node
#
class TextureListImporter(BinaryImporter):
    _textureList = None

    def __init__(self, fd, textureList):
        BinaryImporter.__init__(self, fd)
        self._textureList = textureList

    def readTextureList(self, sizehint=None):
        """Read the texture list section"""
        id, flags, length = self.readTriplet()
        start = self._fd.tell()
        assert id == 14, self._err('Expected Texture List node')
        assert flags == 2, self._err('Texture List node flags not 2')

        count = self.readInt()
        if sizehint is not None:
            assert count == sizehint, self._err(
                "Size hint didn't match actual count")

        for i in range(count):
            importer = TextureImporter(self._fd)
            importer.readTexture(self._textureList, i)

        assert self._fd.tell() == start + length, self._err(
            'Unexpected Texture List node length mismatch')

#
# Texture Node
#
class TextureImporter(BinaryImporter):
    def readTexture(self, textureList, index):
        id, flags, length = self.readTriplet()
        start = self._fd.tell()
        assert id == 15, self._err('Expected Texture node')
        assert flags == 4, self._err('Texture node flags not 4')

        name = self.readString()
        klass = self.readString()

        texture = textureList._createTexture(klass)
        texture._name = name

        # Most of the following only applies to bitmap textures, but the GMI
        # file contains these fields for all texture types.
        texture._bitmap = self.readString()
        texture._amount = self.readFloat()
        texture._type = self.readInt()
        texture._map_type = self.readInt()
        texture._u_offset = self.readFloat()
        texture._v_offset = self.readFloat()
        texture._u_tiling = self.readFloat()
        texture._v_tiling = self.readFloat()
        texture._angle = self.readFloat()
        texture._blur = self.readFloat()
        texture._blur_offset = self.readFloat()
        texture._noise = self.readFloat()
        texture._noise_size = self.readFloat()
        texture._noise_level = self.readInt()
        texture._noise_phase = self.readFloat()

        # The following two fields are speculative; all RA2 files list these as
        # 0. The ASCII export source code shows a inversion export, but no
        # other field.
        texture._invert = self.readInt()
        texture._unknown = self.readInt()

        texture._filter = self.readInt()
        texture._channel = self.readInt()

        sub_count = self.readInt()
        if sub_count:
            importer = TextureListImporter(self._fd, texture._sub_textures)
            importer.readTextureList(sub_count)

        assert self._fd.tell() == start + length, self._err(
            'Unexpected Texture node length mismatch')

#
# Transformable node importer base
#
class TransformableNodeImporter(BinaryImporter):
    def readTMNode(self, _expectedName=None):
        """Read a Transformation matrix node and return the TM."""
        id, flags, length = self.readTriplet()
        start = self._fd.tell()
        assert id == 17, self._err('Expected Transformation Matrix node')
        assert flags == 2, self._err('Transformation Matrix node flags not 2')

        tm_name = self.readString()
        if _expectedName:
            assert _expectedName == tm_name

        matrix = self.readTM()

        assert self._fd.tell() == start + length, self._err(
            'Unexpected Texture node length mismatch')
        return matrix


#
# Import Object List node
#
objectImporters = {}
class ObjectListImporter(BinaryImporter):
    _objectList = None

    def __init__(self, fd, objectList):
        BinaryImporter.__init__(self, fd)
        self._objectList = objectList

    def readObjectList(self):
        """Read the object list section"""
        id, flags, length = self.readTriplet()
        start = self._fd.tell()
        assert id == 18, self._err('Expected Object List node')
        assert flags == 2, self._err('Object List node flags not 2')

        count = self.readInt()

        for i in range(count):
            object_id, object_flags, section_length = self.readTriplet()
            importer = objectImporters.get(object_id, None)
            if not importer:
                raise ImportException, self._err('Unknown object node type')
            importer(self._fd).readObjectNode(self._objectList, object_flags,
                                              section_length)

        # Current GMI files have the object list section lenght incorrect
        # because various object nodes report 0 or incorrect lenght.
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Object List node length mismatch')


#
# Geometry Node import
#
class GeometricObjectNodeImporter(TransformableNodeImporter):
    def readObjectNode(self, objectList, flags, length):
        assert flags == 4, self._err('Geometry Node flags not 4')
        start = self._fd.tell()
        
        geom = objectList._createObject('GeometricObject')
        geom._name = self.readString()
        geom._parent = self.readString()
        geom._shade_verts = self.readBoolean()
        geom._tm = self.readTMNode(geom.getName())
        self.readMesh(geom.getMesh())

        # Current GMI files have the geom node section lenght incorrect
        # because it's mesh node reports 3 to 7 bytes too short.
        # assert self._fd.tell() == start + length, self._err(
        #    'Unexpected Geometric Object node length mismatch')

    def readMesh(self, mesh):
        id, flags, length = self.readTriplet()
        start = self._fd.tell()
        assert id == 16, self._err('Expected Mesh node')
        assert flags == 4, self._err('Object List node flags not 2')

        mesh._time = self.readInt()
        pointcount = self.readInt()
        facecount = self.readInt()
        texturecount = self.readInt()
        colorcount = self.readInt()
        mesh._materialRef = self.readInt()

        points = []
        for i in range(pointcount):
            points.append(self.readPoint())
        mesh._points = tuple(points)

        faces = []
        for i in range(facecount):
            faces.append(self.readIndexSet() + (self.readInt(),))
        mesh._faces = tuple(faces)

        textureCoords = []
        for i in range(texturecount):
            textureCoords.append(self.readFloatTriple())
        mesh._textureCoords = tuple(textureCoords)

        if texturecount:
            textureFaces = []
            for i in range(facecount):
                textureFaces.append(self.readIndexSet())
            mesh._textureFaces = tuple(textureFaces)

        additional_channels = self.readInt()
        if additional_channels:
            self.readTextureChannels(mesh._textureChannels)

        colors = []
        for i in range(colorcount):
            colors.append(self.readFloatTriple())
        mesh._colors = tuple(colors)

        if colorcount:
            colorFaces = []
            for i in range(facecount):
                colorFaces.append(self.readIndexSet())
            mesh._colorFaces = tuple(colorFaces)

        normals = []
        for i in range(facecount):
            for j in range(4):
                normals.append(self.readVector())
        mesh._normals = tuple(normals)

        mesh._backface_cull = self.readInt()

    def readTextureChannels(self, textureChannels):
        for i in range(self.readInt()):
            assert i + 2 == self.readInt(), self._err(
                'Texture Channel index off?')
            channel = textureChannels._createChannel()
            texturecount = self.readInt()
            assert 0 == self.readInt(), self._err(
                'Channel Int 2 not 0') # XXX
            facecount = self.readInt()
            assert 0 == self.readInt(), self._err(
                'Channel Int 4 not 0') # XXX
            assert 0 == self.readInt(), self._err(
                'Channel Int 5 not 0') # XXX
            assert texturecount == self.readInt(), self._err(
                'Expected tex count again') # XXX
            assert facecount == self.readInt(), self._err(
                'Expected face count again') # XXX

            textureCoords = []
            for i in range(texturecount):
                textureCoords.append(self.readPoint())
            channel._textureCoords = tuple(textureCoords)

            if texturecount:
                textureFaces = []
                for i in range(facecount):
                    textureFaces.append(self.readIndexSet())
                channel._textureFaces = tuple(textureFaces)

objectImporters[2] = GeometricObjectNodeImporter


#
# Camera Node import
#
class CameraImporter(TransformableNodeImporter):
    def readObjectNode(self, objectList, flags, length):
        # Import solely based on one camera node in all RA2 files..
        assert flags == 2, self._err('Light Node flags not 3')
        start = self._fd.tell()

        camera = objectList._createObject('Camera')
        camera._name = self.readString()
        camera._tm = self.readTMNode(camera.getName())
        if (self.readInt()):
            camera._target_tm = self.readTMNode()
        camera._type = self.readInt()
        camera._hither = self.readFloat()
        camera._yon = self.readFloat()
        camera._near = self.readFloat()
        camera._far = self.readFloat()
        camera._fov = self.readFloat()
        camera._tdist = self.readFloat()

        # No use, seems to be 4 bytes too short
        # assert self._fd.tell() == start + length, self._err(
        #    'Unexpected Zope node length mismatch')

objectImporters[4] = CameraImporter


#
# Light Node import
#
class LightImporter(TransformableNodeImporter):
    def readObjectNode(self, objectList, flags, length):
        assert flags == 3, self._err('Light Node flags not 3')
        start = self._fd.tell()

        light = objectList._createObject('Light')
        light._name = self.readString()
        light._tm = self.readTMNode(light.getName())

        # These fields are rather speculative; not enough variation in RA2
        # files to be sure; educated guesses from ASE export code.
        light._target = self.readString() 
        if light.getTarget():
            light._target_tm = self.readTMNode(light.getTarget)

        light._type = self.readInt()
        light._shadows = self.readInt()
        light._use_light = self.readInt()
        light._shape = 0 # Doesn't appear to be exported to GMI
        light._color = self.readColor()
        light._intensity = self.readFloat()
        light._aspect = self.readFloat()

        light._unknown = unpack('BBBBBBBB', self._read(8))

        light._attn_start = self.readFloat()
        light._attn_end = self.readFloat()
        light._tdist = self.readFloat()
        light._use_far_attn = self.readByte()
        light._unknown += unpack('BBB', self._read(3))

        # No use checking; seems to be about 6 bytes short.
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Light node length mismatch')
        
objectImporters[5] = LightImporter


#
# Attachment Point
#
class AttachmentPointImporter(TransformableNodeImporter):
    def readObjectNode(self, objectList, flags, length):
        assert flags == 2, self._err('Attachment Point Node flags not 2')
        start = self._fd.tell()
        
        point = objectList._createObject('AttachmentPoint')
        point._name = self.readString()
        point._tm = self.readTMNode(point.getName())
        point._setUserData(self.readString())

        assert self._fd.tell() == start + length, self._err(
            'Unexpected Attachment Point node length mismatch')
    
objectImporters[21] = AttachmentPointImporter


#
# Simulation Object import
#
class SimulationObjectImporter(BinaryImporter):
    def readObjectNode(self, objectList, flags, length):
        assert flags == 2, self._err('Simulation Object Node flags not 2')
        start = self._fd.tell()

        sim = objectList._createObject('SimulationObject')
        sim._name = self.readString()
        sim._gravity = self.readVector()
        sim._worldscale = self.readFloat()
        sim._simtolerance = self.readFloat()
        sim._resolver = self.readInt()
        sim._incl_drag = self.readByte()
        sim._linear_drag = self.readFloat()
        sim._angular_drag = self.readFloat()
        sim._incl_deactivator = self.readByte()
        sim._shortfreq = self.readFloat()
        sim._longfreq = self.readFloat()
        sim._fast_subspace = self.readByte()
        sim._updates_per_timestep = self.readFloat()
        sim._coll_pairs = self.readInt()

        # No point, seems to be about 4 bytes short
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Simulation Object node length mismatch')

objectImporters[30] = SimulationObjectImporter


#
# Constraint Solver node import
#
class ConstraintSolverImporter(TransformableNodeImporter):
    def readObjectNode(self, objectList, flags, length):
        assert flags == 3, self._err('Constraint Solver Node flags not 3')
        start = self._fd.tell()

        solver = objectList._createObject('ConstraintSolver')
        solver._name = self.readString()
        solver._treshold = self.readFloat()
        solver._rb_coll = self.readString()
        
        constraints = self.readInt()
        if constraints:
            self.readConstraintList(constraints, solver._constraints)

        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Constraint Solver node length mismatch')

    constraintImporters = {}
    def readConstraintList(self, sizehint, constraintList):
        id, flags, length = self.readTriplet()
        assert id == 44, self._err('Expected Constraint List node')
        assert flags == 2, self._err('Constraint List Node flags not 2')
        start = self._fd.tell()

        count = self.readInt()
        assert count == sizehint, self._err(
            'Inconsistent ConstraintList item count')

        for i in range(count):
            node_id, node_flags, subnode_length = self.readTriplet()
            importer = getattr(self,
               self.constraintImporters.get(node_id, '_unknown'), None)
            if not importer:
                raise ImportException, self._err('Unknown contraint node type')
            importer(constraintList, node_flags, subnode_length)

        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Constraint List node length mismatch')

    constraintImporters[46] = 'readPivotConstraint'
    def readPivotConstraint(self, constraintList, flags, lenght):
        assert flags == 2, self._err('Pivot Constraint Node flags not 2')
        start = self._fd.tell()

        hinge = constraintList._createConstraint('PivotConstraint')
        hinge._name = self.readString()
        hinge._tm = self.readTMNode(hinge.getName())
        hinge._body1 = self.readString()
        hinge._body2 = self.readString()
        hinge._point = self.readPoint()
        hinge._spin_axis = self.readVector()
        hinge._unknown = (self.readFloat(), self.readFloat(), self.readFloat(), 
                          self.readFloat(), self.readFloat(), self.readFloat(), 
                          self.readFloat(), self.readFloat())

        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Constraint List node length mismatch')

    constraintImporters[47] = 'readHingeConstraint'
    def readHingeConstraint(self, constraintList, flags, lenght):
        assert flags == 2, self._err('Hinge Constraint Node flags not 2')
        start = self._fd.tell()

        hinge = constraintList._createConstraint('HingeConstraint')
        hinge._name = self.readString()
        hinge._tm = self.readTMNode(hinge.getName())
        hinge._body1 = self.readString()
        hinge._body2 = self.readString()
        hinge._point = self.readPoint()
        hinge._spin_axis = self.readVector()
        hinge._is_limited = self.readByte()
        hinge._friction = self.readFloat()
        hinge._angle_limits = (self.readFloat(), self.readFloat())

        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Constraint List node length mismatch')

    constraintImporters[53] = 'readPointToPointConstraint'
    def readPointToPointConstraint(self, constraintList, flags, lenght):
        assert flags == 2, self._err(
            'Point-to-point Constraint Node flags not 2')
        start = self._fd.tell()

        hinge = constraintList._createConstraint('PointToPointConstraint')
        hinge._name = self.readString()
        hinge._tm = self.readTMNode(hinge.getName())
        hinge._body1 = self.readString()
        hinge._body2 = self.readString()
        hinge._point1 = self.readPoint()
        hinge._point2 = self.readPoint()

        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Constraint List node length mismatch')

objectImporters[42] = ConstraintSolverImporter


#
# Angular Dashpot Importer
#
class AngularDashpotImporter(TransformableNodeImporter):
    def readObjectNode(self, objectList, flags, length):
        assert flags == 2, self._err('Angular Dashpot Node flags not 2')
        start = self._fd.tell()

        adashpot = objectList._createObject('AngularDashpot')
        adashpot._name = self.readString()
        adashpot._tm = self.readTMNode(adashpot.getName())
        adashpot._body1 = self.readString()
        adashpot._body2 = self.readString()
        adashpot._strength = self.readFloat()
        adashpot._damping = self.readFloat()
        adashpot._allow_interpenetrations = self.readByte()
        adashpot._quad = (self.readFloat(), self.readFloat(), self.readFloat(), 
                          self.readFloat())

        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Angular Dashpot node length mismatch')

objectImporters[49] = AngularDashpotImporter


#
# Rigid Body Collection importer
#
class RigidBodyCollectionImporter(TransformableNodeImporter):
    def readObjectNode(self, objectList, flags, length):
        assert flags == 4, self._err('Rigid Body Collection Node flags not 4')
        start = self._fd.tell()

        rbcollection = objectList._createObject('RigidBodyCollection')
        rbcollection._name = self.readString()
        paircount = self.readInt()
        rbcollection._solver_type = self.readInt()

        self.readRigidBodyList(rbcollection._rigid_bodies)
        if paircount:
            self.readDisabledCollisionPairs(rbcollection, paircount)
    
        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Rigid Body Collection node length mismatch')

    def readRigidBodyList(self, rb_list, sizehint=None):
        id, flags, length = self.readTriplet()
        assert id == 33, self._err('Expected Rigid Body List node')
        assert flags == 2, self._err('Rigid Body List Node flags not 2')
        start = self._fd.tell()

        count = self.readInt()
        if sizehint is not None:
            assert sizehint == count, self._err(
                'Inconsistent rigid body list count?')

        for i in range(count):
            self.readRigidBody(rb_list)

        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Rigid Body List node length mismatch')

    def readRigidBody(self, rb_list):
        id, flags, length = self.readTriplet()
        assert id == 32, self._err('Expected Rigid Body List node')
        assert flags == 4, self._err('Rigid Body Node flags not 4')
        start = self._fd.tell()

        rbody = rb_list._createRigidBody()
        rbody._name = self.readString()
        rbody._mass = self.readFloat()
        rbody._elasticity = self.readFloat()
        rbody._friction = self.readFloat()
        rbody._opt_lvl = self.readFloat()
        rbody._unyielding = self.readInt()
        rbody._sim_geom = self.readInt()
        rbody._geom_proxy_name = self.readString()
        rbody._use_display_proxy = self.readByte()
        rbody._disable_collisions = self.readByte()
        rbody._inactive = self.readByte()
        rbody._display_proxy_name = self.readString()
        rbody._tm = self.readTMNode(rbody.getName())
        rbody._geo_type = self.readInt()

        childcount = self.readInt()
        if childcount:
            self.readRigidBodyList(rbody._children, childcount)

        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Rigid Body node length mismatch')

    def readDisabledCollisionPairs(self, rbcollection, sizehint):
        id, flags, length = self.readTriplet()
        assert id == 51, self._err('Expected Disabled Collision Pairs node')
        assert flags == 2, self._err(
            'Disabled Collision Pairs Node flags not 2')
        start = self._fd.tell()

        count = self.readInt()
        assert sizehint == count, self._err(
            'Inconsistent count for Disabled Collision Pairs?')

        pairs = []
        for i in range(count):
            pairs.append((self.readString(), self.readString()))

        rbcollection._disabled_collision_pairs = tuple(pairs)

        # No point, no length given
        # assert self._fd.tell() == start + length, self._err(
        #     'Unexpected Disabled Collision Pairs node length mismatch')

objectImporters[31] = RigidBodyCollectionImporter
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.