Exemple #1
0
 def save(self):
     """Saves the light's properties back to :attr:`xmlnode`"""
     self.xmlnode.set('id', self.id)
     self.xmlnode.set('name', self.id)
     colornode = self.xmlnode.find( '%s/%s/%s'%(tag('technique_common'),tag('directional'), 
                                               tag('color') ) )
     colornode.text = ' '.join(map(str, self.color))
Exemple #2
0
    def __init__(self, controller, materials, xmlnode=None):
        """Creates a controller node

        :param collada.controller.Controller controller:
          A controller to instantiate in the scene
        :param list materials:
          A list containing items of type :class:`collada.scene.MaterialNode`.
          Each of these represents a material that the controller should be
          bound to.
        :param xmlnode:
          When loaded, the xmlnode it comes from

        """
        self.controller = controller
        """ An object of type :class:`collada.controller.Controller` representing
        the controller being instantiated in the scene"""
        self.materials = materials
        """A list containing items of type :class:`collada.scene.MaterialNode`.
          Each of these represents a material that the controller is bound to."""
        if xmlnode != None:
            self.xmlnode = xmlnode
            """ElementTree representation of the controller node."""
        else:
            self.xmlnode = ElementTree.Element( tag('instance_controller') )
            bindnode = ElementTree.Element( tag('bind_material') )
            technode = ElementTree.Element( tag('technique_common') )
            bindnode.append( technode )
            self.xmlnode.append( bindnode )
            for mat in materials: technode.append( mat.xmlnode )
Exemple #3
0
 def load( collada, localscope, node ):
     sourceid = node.get('id')
     arraynode = node.find(tag('float_array'))
     if arraynode is None: raise DaeIncompleteError('No float_array in source node')
     if arraynode.text is None:
         data = numpy.array([], dtype=numpy.float32)
     else:
         try: data = numpy.fromstring(arraynode.text, dtype=numpy.float32, sep=' ')
         except ValueError: raise DaeMalformedError('Corrupted float array')
     data[numpy.isnan(data)] = 0
         
     paramnodes = node.findall('%s/%s/%s'%(tag('technique_common'), tag('accessor'), tag('param')))
     if not paramnodes: raise DaeIncompleteError('No accessor info in source node')
     components = [ param.get('name') for param in paramnodes ]
     if len(components) == 2 and components[0] == 'U' and components[1] == 'V':
         #U,V is used for "generic" arguments - convert to S,T
         components = ['S', 'T']
     if len(components) == 3 and components[0] == 'S' and components[1] == 'T' and components[2] == 'P':
         components = ['S', 'T']
         data.shape = (-1, 3)
         #remove 3d texcoord dimension because we don't support it
         #TODO
         data = numpy.array(zip(data[:,0], data[:,1]))
         data.shape = (-1)
     return FloatSource( sourceid, data, tuple(components), xmlnode=node )
Exemple #4
0
 def load(collada, localscope, node):
     colornode = node.find( '%s/%s/%s'%(tag('technique_common'),tag('directional'), 
                                        tag('color') ) )
     if colornode is None: raise DaeIncompleteError('Missing color for directional light')
     try: color = tuple( [ float(v) for v in colornode.text.split() ] )
     except ValueError, ex: 
         raise DaeMalformedError('Corrupted color values in light definition')
Exemple #5
0
    def __init__(self, id, path, collada = None, xmlnode = None):
        """Create an image object.
        
        :Parameters:
          id
            Id of the image node for later reference
          path
            Path in the [zae, kmz] file space
          collada
            The Collada class instance containing this for file access
          xmlnode
            If loaded from xml, the node this data comes from

        """
        self.id = id
        self.path = path
        self.collada = collada
        self._data = None
        self._pilimage = None
        self._uintarray = None
        self._floatarray = None
        if xmlnode != None: self.xmlnode = xmlnode
        else:
            self.xmlnode = ElementTree.Element( tag('image') )
            initnode = ElementTree.Element( tag('init_from') )
            initnode.text = path
            self.xmlnode.append(initnode)
            self.xmlnode.set('id', id)
            self.xmlnode.set('name', id)
Exemple #6
0
    def __init__(self, symbol, target, inputs, xmlnode = None):
        """Create a MaterialNode.

        :Parameters:
          symbol
            The symbol string (inside the geometry object) we are defining
          target
            The id of the material to assign to the symbol
          inputs
            A list of tuples (semantic, input_semantic, set) mapping geometry
            texcoords or other inputs to material input channels (semantic)
          xmlnode
            If loaded from XML, the node it comes from

        """
        self.symbol = symbol
        """The symbol string (inside the geometry object) we are defining."""
        self.target = target
        """The id of the material to assign to the symbol."""
        self.inputs = inputs
        """A list of tuples (semantic, input_semantic, set) mapping material inputs."""
        if xmlnode is not None: self.xmlnode = xmlnode
        else:
            self.xmlnode = ElementTree.Element( tag('instance_material') )
            self.xmlnode.set('symbol', symbol)
            self.xmlnode.set('target', '#' + target.id)
            for sem, input_sem, set in inputs:
                inputnode = ElementTree.ElementTree( tag('bind_vertex_input') )
                inputnode.set('semantic', sem)
                inputnode.set('input_semantic', input_sem)
                inputnode.set('input_set', set)
                self.xmlnode.append( inputnode )
Exemple #7
0
    def __init__(self, controller, materials, xmlnode=None):
        """Creates a controller node

        :param collada.controller.Controller controller:
          A controller to instantiate in the scene
        :param list materials:
          A list containing items of type :class:`collada.scene.MaterialNode`.
          Each of these represents a material that the controller should be
          bound to.
        :param xmlnode:
          When loaded, the xmlnode it comes from

        """
        self.controller = controller
        """ An object of type :class:`collada.controller.Controller` representing
        the controller being instantiated in the scene"""
        self.materials = materials
        """A list containing items of type :class:`collada.scene.MaterialNode`.
          Each of these represents a material that the controller is bound to."""
        if xmlnode != None:
            self.xmlnode = xmlnode
            """ElementTree representation of the controller node."""
        else:
            self.xmlnode = ElementTree.Element(
                collada.tag('instance_controller'))
            bindnode = ElementTree.Element(collada.tag('bind_material'))
            technode = ElementTree.Element(collada.tag('technique_common'))
            bindnode.append(technode)
            self.xmlnode.append(bindnode)
            for mat in materials:
                technode.append(mat.xmlnode)
Exemple #8
0
    def save(self):
        """Saves the geometry node back to :attr:`xmlnode`"""
        self.xmlnode.set('url', "#%s" % self.geometry.id)
        
        for m in self.materials:
            m.save()
        
        matparent = self.xmlnode.find('%s/%s'%( tag('bind_material'), tag('technique_common') ) )
        if matparent is None and len(self.materials)==0:
            return
        elif matparent is None:
            matparent = E.technique_common()
            self.xmlnode.append(E.bind_material(matparent))
        elif len(self.materials) == 0 and matparent is not None:
            bindnode = self.xmlnode.find('%s' % tag('bind_material'))
            self.xmlnode.remove(bindnode)
            return

        for m in self.materials:
            if m.xmlnode not in matparent:
                matparent.append(m.xmlnode)
        xmlnodes = [m.xmlnode for m in self.materials]
        for n in matparent:
            if n not in xmlnodes:
                matparent.remove(n)
Exemple #9
0
    def load( collada, localscope, node ):
        indexnode = node.find(tag('p'))
        if indexnode is None: raise DaeIncompleteError('Missing index in polylist')
        vcountnode = node.find(tag('vcount'))
        if vcountnode is None: raise DaeIncompleteError('Missing vcount in polylist')

        try:
            if vcountnode.text is None:
                vcounts = numpy.array([], dtype=numpy.int32)
            else:
                vcounts = numpy.fromstring(vcountnode.text, dtype=numpy.int32, sep=' ')
            vcounts[numpy.isnan(vcounts)] = 0
        except ValueError, ex: raise DaeMalformedError('Corrupted vcounts in polylist')

        all_inputs = primitive.Primitive._getInputs(collada, localscope, node.findall(tag('input')))

        try:
            if indexnode.text is None:
                index = numpy.array([], dtype=numpy.int32)
            else:
                index = numpy.fromstring(indexnode.text, dtype=numpy.int32, sep=' ')
            index[numpy.isnan(index)] = 0
        except: raise DaeMalformedError('Corrupted index in polylist')

        polylist = Polylist(all_inputs, node.get('material'), index, vcounts, node)
        return polylist
Exemple #10
0
 def findInput(self, semantic):
     """Return the xml node assigning something to `semantic`."""
     for node in self.xmlnode.findall(tag('bind_vertex_input')):
         if node.get('semantic') == semantic: return node
     node = ElementTree.Element(tag('bind_vertex_input'))
     node.set('semantic', semantic)
     self.xmlnode.append( node )
     return node
Exemple #11
0
 def load(collada, localscope, node):
     colornode = node.find("%s/%s/%s" % (tag("technique_common"), tag("directional"), tag("color")))
     if colornode is None:
         raise DaeIncompleteError("Missing color for directional light")
     try:
         color = tuple([float(v) for v in colornode.text.split()])
     except ValueError, ex:
         raise DaeMalformedError("Corrupted color values in light definition")
Exemple #12
0
 def save(self):
     surfacenode = self.xmlnode.find( tag('surface') )
     initnode = surfacenode.find( tag('init_from') )
     if self.format:
         formatnode = surfacenode.find( tag('format') )
         formatnode.text = self.format
     initnode.text = self.image.id
     self.xmlnode.set('sid', self.id)
Exemple #13
0
 def save(self):
     #TODO: Update this with new sourceById format
     for ch in self.sources: ch.save()
     vnode = self.xmlnode.find(tag('mesh')).find(tag('vertices'))
     vinput = vnode.find(tag('input'))
     vnode.set('id', self.vertexsource)
     vinput.set('source', '#'+self.sourceById[self.vertexsource].id)
     for t in self._primitives: t.save()
     self.xmlnode.set('id', self.id)
     self.xmlnode.set('name', self.id)
Exemple #14
0
 def load( collada, node ):
     url = node.get('url')
     if not url.startswith('#'): raise DaeMalformedError('Invalid url in geometry instance')
     geometry = collada.geometryById.get(url[1:])
     if not geometry: raise DaeBrokenRefError('Geometry %s not found in library'%url)
     matnodes = node.findall('%s/%s/%s'%( tag('bind_material'), tag('technique_common'), tag('instance_material') ) )
     materials = []
     for matnode in matnodes:
         materials.append( MaterialNode.load(collada, matnode) )
     return GeometryNode( geometry, materials, xmlnode=node)
Exemple #15
0
 def load( collada, node ):
     url = node.get('url')
     if not url.startswith('#'): raise DaeMalformedError('Invalid url in controller instance')
     controller = collada.controllerById.get(url[1:])
     if not controller: raise DaeBrokenRefError('Controller %s not found in library'%url)
     matnodes = node.findall('%s/%s/%s'%( tag('bind_material'), tag('technique_common'), tag('instance_material') ) )
     materials = []
     for matnode in matnodes:
         materials.append( MaterialNode.load(collada, matnode) )
     return ControllerNode( controller, materials, xmlnode=node)
Exemple #16
0
 def save(self):
     samplernode = self.xmlnode.find( tag('sampler2D') )
     sourcenode = samplernode.find( tag('source') )
     if self.minfilter:
         minnode = samplernode.find( tag('minfilter') )
         minnode.text = self.minfilter
     if self.maxfilter:
         maxnode = samplernode.find( tag('maxfilter') )
         maxnode.text = self.maxfilter
     sourcenode.text = self.surface.id
     self.xmlnode.set('sid', self.id)
Exemple #17
0
 def load(collada, localscope, node):
     tecnode = node.find( '%s/%s' % (tag('optics'),tag('technique_common')) )
     if tecnode is None or len(tecnode) == 0: 
         raise DaeIncompleteError('Missing common technique in camera')
     camnode = tecnode[0]
     if camnode.tag == tag('perspective'):
         return PerspectiveCamera.load( collada, localscope, node )
     elif camnode.tag == tag('orthographic'):
         return OrthographicCamera.load( collada, localscope, node )
     else:
         raise DaeUnsupportedError('Unrecognized camera type: %s'%camnode.tag)
Exemple #18
0
 def save(self):
     """Saves the light's properties back to :attr:`xmlnode`"""
     self.xmlnode.set('id', self.id)
     self.xmlnode.set('name', self.id)
     pnode = self.xmlnode.find( '%s/%s'%(tag('technique_common'),tag('point')) )
     colornode = pnode.find( tag('color') )
     colornode.text = ' '.join(map(str, self.color ) )
     Light._correctValInNode(pnode, 'constant_attenuation', self.constant_att)
     Light._correctValInNode(pnode, 'linear_attenuation', self.linear_att)
     Light._correctValInNode(pnode, 'quadratic_attenuation', self.quad_att)
     Light._correctValInNode(pnode, 'zfar', self.zfar)
Exemple #19
0
 def save(self):
     txtdata = ' '.join([ f for f in self.data ])
     node = self.xmlnode.find(tag('Name_array'))
     node.text = txtdata
     node.set('count', str(len(self.data)))
     node.set('id', self.id+'-array' )
     node = self.xmlnode.find('%s/%s'%(tag('technique_common'), tag('accessor')))
     node.set('count', str(len(self.components)))
     node.set('source', '#'+self.id+'-array')
     node.set('stride', str(len(self.components)))
     self.xmlnode.set('id', self.id )
Exemple #20
0
 def save(self):
     """Saves the light's properties back to :attr:`xmlnode`"""
     self.xmlnode.set("id", self.id)
     self.xmlnode.set("name", self.id)
     pnode = self.xmlnode.find("%s/%s" % (tag("technique_common"), tag("point")))
     colornode = pnode.find(tag("color"))
     colornode.text = " ".join(map(str, self.color))
     _correctValInNode(pnode, "constant_attenuation", self.constant_att)
     _correctValInNode(pnode, "linear_attenuation", self.linear_att)
     _correctValInNode(pnode, "quadratic_attenuation", self.quad_att)
     _correctValInNode(pnode, "zfar", self.zfar)
Exemple #21
0
    def load( collada, localscope, node ):
        indexnodes = node.findall(tag('p'))
        if indexnodes is None: raise DaeIncompleteError('Missing indices in polygons')

        polygon_indices = []
        for indexnode in indexnodes:
            polygon_indices.append(numpy.fromstring(indexnode.text, dtype=numpy.int32, sep=' '))
        
        all_inputs = primitive.Primitive._getInputs(localscope, node.findall(tag('input')))

        polygons = Polygons(all_inputs, node.get('material'), polygon_indices, node)
        return polygons
Exemple #22
0
 def save(self):
     """Saves the surface data back to :attr:`xmlnode`"""
     surfacenode = self.xmlnode.find( tag('surface') )
     initnode = surfacenode.find( tag('init_from') )
     if self.format:
         formatnode = surfacenode.find( tag('format') )
         if formatnode is None:
             surfacenode.append(E.format(self.format))
         else:
             formatnode.text = self.format
     initnode.text = self.image.id
     self.xmlnode.set('sid', self.id)
Exemple #23
0
 def save(self):
     """Saves the sampler data back to :attr:`xmlnode`"""
     samplernode = self.xmlnode.find( tag('sampler2D') )
     sourcenode = samplernode.find( tag('source') )
     if self.minfilter:
         minnode = samplernode.find( tag('minfilter') )
         minnode.text = self.minfilter
     if self.magfilter:
         maxnode = samplernode.find( tag('magfilter') )
         maxnode.text = self.magfilter
     sourcenode.text = self.surface.id
     self.xmlnode.set('sid', self.id)
Exemple #24
0
 def load(collada, localscope, node):
     author = node.find( tag('author') )
     authoring_tool = node.find( tag('authoring_tool') )
     comments = node.find( tag('comments') )
     copyright = node.find( tag('copyright') )
     source_data = node.find( tag('source_data') )
     if author is not None: author = author.text
     if authoring_tool is not None: authoring_tool = authoring_tool.text
     if comments is not None: comments = comments.text
     if copyright is not None: copyright = copyright.text
     if source_data is not None: source_data = source_data.text
     return Contributor(author=author, authoring_tool=authoring_tool,
                        comments=comments, copyright=copyright, source_data=source_data, xmlnode=node)
Exemple #25
0
 def load( collada, localscope, node ):
     indexnode = node.find(tag('p'))
     if indexnode is None: raise DaeIncompleteError('Missing index in triangle set')
     
     source_array = primitive.Primitive.getInputs(localscope, node.findall(tag('input')))
         
     try:
         index = numpy.array([float(v) for v in indexnode.text.split()], dtype=numpy.int32)
     except: raise DaeMalformedError('Corrupted index in triangleset')
     
     triset = TriangleSet(source_array, node.get('material'), index)
     triset.xmlnode = node
     return triset
Exemple #26
0
 def load(collada, localscope, node):
     tecnode = node.find(tag("technique_common"))
     if tecnode is None or len(tecnode) == 0:
         raise DaeIncompleteError("Missing common technique in light")
     lightnode = tecnode[0]
     if lightnode.tag == tag("directional"):
         return SunLight.load(collada, localscope, node)
     elif lightnode.tag == tag("point"):
         return PointLight.load(collada, localscope, node)
     elif lightnode.tag == tag("ambient"):
         return AmbientLight.load(collada, localscope, node)
     else:
         raise DaeUnsupportedError("Unrecognized light type: %s" % lightnode.tag)
Exemple #27
0
 def load( collada, localscope, node ):
     surfacenode = node.find( tag('surface') )
     if surfacenode is None: raise DaeIncompleteError('No surface found in newparam')
     if surfacenode.get('type') != '2D': raise DaeMalformedError('Hard to imagine a non-2D surface, isn\'t it?')
     initnode = surfacenode.find( tag('init_from') )
     if initnode is None: raise DaeIncompleteError('No init image found in surface')
     formatnode = surfacenode.find( tag('format') )
     if formatnode is None: format = None #raise Exception('No format found in surface')
     else: format = formatnode.text
     imgid = initnode.text
     id = node.get('sid')
     img = collada.imageById.get(imgid)
     if img is None: raise DaeBrokenRefError('Missing image ' + imgid)
     return Surface(id, img, format, xmlnode=node)
Exemple #28
0
 def load( collada, localscope, node ):
     sourceid = node.get('id')
     arraynode = node.find(tag('Name_array'))
     if arraynode is None: raise DaeIncompleteError('No Name_array in source node')
     if arraynode.text is None:
         values = []
     else:
         try: values = [v for v in arraynode.text.split()]
         except ValueError: raise DaeMalformedError('Corrupted Name array')
     data = numpy.array( values, dtype=numpy.string_ )
     paramnodes = node.findall('%s/%s/%s'%(tag('technique_common'), tag('accessor'), tag('param')))
     if not paramnodes: raise DaeIncompleteError('No accessor info in source node')
     components = [ param.get('name') for param in paramnodes ]
     return NameSource( sourceid, data, tuple(components), xmlnode=node )
Exemple #29
0
 def save(self):
     self.data.shape = (-1,)
     txtdata = ' '.join([ str(f) for f in self.data ])#str(self.data)[1:-1]
     rawlen = len( self.data )
     self.data.shape = (-1, len(self.components) )
     acclen = len( self.data )
     node = self.xmlnode.find(tag('float_array'))
     node.text = txtdata
     node.set('count', str(rawlen))
     node.set('id', self.id+'-array' )
     node = self.xmlnode.find('%s/%s'%(tag('technique_common'), tag('accessor')))
     node.set('count', str(acclen))
     node.set('source', '#'+self.id+'-array')
     node.set('stride', str(len(self.components)))
     self.xmlnode.set('id', self.id )
Exemple #30
0
 def load(collada, localscope, node):
     tecnode = node.find( tag('technique_common') )
     if tecnode is None or len(tecnode) == 0: 
         raise DaeIncompleteError('Missing common technique in light')
     lightnode = tecnode[0]
     if lightnode.tag == tag('directional'):
         return DirectionalLight.load( collada, localscope, node )
     elif lightnode.tag == tag('point'):
         return PointLight.load( collada, localscope, node )
     elif lightnode.tag == tag('ambient'):
         return AmbientLight.load( collada, localscope, node )
     elif lightnode.tag == tag('spot'):
         return SpotLight.load( collada, localscope, node )
     else:
         raise DaeUnsupportedError('Unrecognized light type: %s'%lightnode.tag)
Exemple #31
0
 def load(collada, localscope, node):
     sourceid = node.get('id')
     arraynode = node.find(tag('float_array'))
     if not arraynode is None:
         return FloatSource.load(collada, localscope, node)
     
     arraynode = node.find(tag('IDREF_array'))
     if not arraynode is None:
         return IDRefSource.load(collada, localscope, node)
     
     arraynode = node.find(tag('Name_array'))
     if not arraynode is None:
         return NameSource.load(collada, localscope, node)
     
     if arraynode is None: raise DaeIncompleteError('No array found in source %s' % sourceid)
Exemple #32
0
 def load(collada, node):
     url = node.get('url')
     if not url.startswith('#'):
         raise DaeMalformedError('Invalid url in controller instance %s' %
                                 url)
     controller = collada.controllers.get(url[1:])
     if not controller:
         raise DaeBrokenRefError('Controller %s not found in library' % url)
     matnodes = node.findall(
         '%s/%s/%s' %
         (collada.tag('bind_material'), collada.tag('technique_common'),
          collada.tag('instance_material')))
     materials = []
     for matnode in matnodes:
         materials.append(MaterialNode.load(collada, matnode))
     return ControllerNode(controller, materials, xmlnode=node)
Exemple #33
0
 def load(collada, node):
     url = node.get('url')
     if not url.startswith('#'):
         raise DaeMalformedError('Invalid url in geometry instance %s' %
                                 url)
     geometry = collada.geometries.get(url[1:])
     if not geometry:
         raise DaeBrokenRefError('Geometry %s not found in library' % url)
     matnodes = node.findall(
         '%s/%s/%s' %
         (collada.tag('bind_material'), collada.tag('technique_common'),
          collada.tag('instance_material')))
     materials = []
     for matnode in matnodes:
         materials.append(MaterialNode.load(collada, matnode))
     return GeometryNode(geometry, materials, xmlnode=node)
Exemple #34
0
 def load(collada, node):
     inputs = []
     for inputnode in node.findall(collada.tag('bind_vertex_input')):
         inputs.append(
             (inputnode.get('semantic'), inputnode.get('input_semantic'),
              inputnode.get('input_set')))
     targetid = node.get('target')
     if not targetid.startswith('#'):
         raise DaeMalformedError('Incorrect target id in material ' +
                                 targetid)
     target = collada.materials.get(targetid[1:])
     if not target:
         raise DaeBrokenRefError('Material %s not found' % targetid)
     return MaterialNode(node.get('symbol'), target, inputs, xmlnode=node)
Exemple #35
0
    def load(collada, node):
        id = node.get('id')
        nodes = []
        tried_loading = []
        succeeded = False
        localscope = {}
        for nodenode in node.findall(collada.tag('node')):
            try:
                N = loadNode(collada, nodenode, localscope)
            except DaeInstanceNotLoadedError as ex:
                tried_loading.append((nodenode, ex))
            except DaeError as ex:
                collada.handleError(ex)
            else:
                if N is not None:
                    nodes.append(N)
                    if N.id and N.id not in localscope:
                        localscope[N.id] = N
                    succeeded = True
        while len(tried_loading) > 0 and succeeded:
            succeeded = False
            next_tried = []
            for nodenode, ex in tried_loading:
                try:
                    N = loadNode(collada, nodenode, localscope)
                except DaeInstanceNotLoadedError as ex:
                    next_tried.append((nodenode, ex))
                except DaeError as ex:
                    collada.handleError(ex)
                else:
                    if N is not None:
                        nodes.append(N)
                        succeeded = True
            tried_loading = next_tried
        if len(tried_loading) > 0:
            for nodenode, ex in tried_loading:
                raise DaeBrokenRefError(ex.msg)

        return Scene(id, nodes, xmlnode=node, collada=collada)
Exemple #36
0
def loadNode(collada, node, localscope):
    """Generic scene node loading from an xml `node` and a `collada` object.

    Knowing the supported nodes, create the appropriate class for the given node
    and return it.

    """
    if node.tag == collada.tag('node'):
        return Node.load(collada, node, localscope)
    elif node.tag == collada.tag('translate'):
        return TranslateTransform.load(collada, node)
    elif node.tag == collada.tag('rotate'):
        return RotateTransform.load(collada, node)
    elif node.tag == collada.tag('scale'):
        return ScaleTransform.load(collada, node)
    elif node.tag == collada.tag('matrix'):
        return MatrixTransform.load(collada, node)
    elif node.tag == collada.tag('lookat'):
        return LookAtTransform.load(collada, node)
    elif node.tag == collada.tag('instance_geometry'):
        return GeometryNode.load(collada, node)
    elif node.tag == collada.tag('instance_camera'):
        return CameraNode.load(collada, node)
    elif node.tag == collada.tag('instance_light'):
        return LightNode.load(collada, node)
    elif node.tag == collada.tag('instance_controller'):
        return ControllerNode.load(collada, node)
    elif node.tag == collada.tag('instance_node'):
        return NodeNode.load(collada, node, localscope)
    elif node.tag == collada.tag('extra'):
        return ExtraNode.load(collada, node)
    elif node.tag == collada.tag('asset'):
        return None
    else:
        raise DaeUnsupportedError('Unknown scene node %s' % str(node.tag))