Ejemplo n.º 1
0
  def __init__(self, textures, shader, camera=None, light=None, w=1.0, h=1.0, name="",
               x=0.0, y=0.0, z=20.0,
               rx=0.0, ry=0.0, rz=0.0,
               sx=1.0, sy=1.0, sz=1.0,
               cx=0.0, cy=0.0, cz=0.0):
    """Uses standard constructor for Shape. Arguments:
      *textures*
        must be a two dimensional list of lists of textures or strings 
        (which must be the path/names of image files) The array runs left
        to right then down so six textures in spreadsheet notation would be
        
        [[R1C1, R1C2], [R2C1, R2C2], [R3C1, R3C2]]
        
      *shader*
        shader to use
        
      Extra keyword arguments:  
        
      *w*
        Width.
      *h*
        Height.
    """
    try:
      nh = len(textures)
      nw = len(textures[0])
      super(MultiSprite, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                   sx, sy, sz, cx, cy, cz)
      self.width = w
      self.height = h
      ww = w / 2.0 / nw
      hh = h / 2.0 / nh
      self.buf = []
      for i in range(nw):
        for j in range(nh):
          offw = w * ((1.0 - nw) / 2.0 + i) / nw
          offh = -h * ((1.0 - nh) / 2.0 + j) / nh
          verts = ((-ww + offw, hh + offh, 0.0), 
                        (ww + offw, hh + offh, 0.0), 
                        (ww + offw, -hh + offh, 0.0), 
                        (-ww + offw, -hh + offh, 0.0))
          norms = ((0, 0, -1), (0, 0, -1),  (0, 0, -1), (0, 0, -1))
          texcoords = ((0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0 , 1.0))

          inds = ((0, 1, 3), (1, 2, 3))

          thisbuf = Buffer(self, verts, texcoords, inds, norms)
          if not isinstance(textures[j][i], Texture): # i.e. can load from file name
            textures[j][i] = Texture(textures[j][i])
          thisbuf.textures = [textures[j][i]]
          self.buf.append(thisbuf)
      self.set_shader(shader)
      self.set_2d_size() # method in Shape, default full window size
    except IndexError:
      LOGGER.error('Must supply a list of lists of Textures or strings')
Ejemplo n.º 2
0
    def __init__(self,
                 textures,
                 shader,
                 camera=None,
                 light=None,
                 w=1.0,
                 h=1.0,
                 name="",
                 x=0.0,
                 y=0.0,
                 z=20.0,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 sx=1.0,
                 sy=1.0,
                 sz=1.0,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """Uses standard constructor for Shape. Arguments:
      *textures*
        must be a two dimensional list of lists of textures or strings 
        (which must be the path/names of image files) The array runs left
        to right then down so six textures in spreadsheet notation would be
        
        [[R1C1, R1C2], [R2C1, R2C2], [R3C1, R3C2]]
        
      *shader*
        shader to use
        
      Extra keyword arguments:  
        
      *w*
        Width.
      *h*
        Height.
    """
        try:
            nh = len(textures)
            nw = len(textures[0])
            super(MultiSprite, self).__init__(camera, light, name, x, y, z, rx,
                                              ry, rz, sx, sy, sz, cx, cy, cz)
            self.width = w
            self.height = h
            self.ttype = GL_TRIANGLES
            self.verts = []
            self.norms = []
            self.texcoords = []
            self.inds = []

            ww = w / 2.0 / nw
            hh = h / 2.0 / nh
            self.buf = []
            for i in range(nw):
                for j in range(nh):
                    offw = w * ((1.0 - nw) / 2.0 + i) / nw
                    offh = -h * ((1.0 - nh) / 2.0 + j) / nh
                    self.verts = ((-ww + offw, hh + offh,
                                   0.0), (ww + offw, hh + offh,
                                          0.0), (ww + offw, -hh + offh, 0.0),
                                  (-ww + offw, -hh + offh, 0.0))
                    self.norms = ((0, 0, -1), (0, 0, -1), (0, 0, -1), (0, 0,
                                                                       -1))
                    self.texcoords = ((0.0, 0.0), (1.0, 0.0), (1.0, 1.0),
                                      (0.0, 1.0))

                    self.inds = ((0, 1, 3), (1, 2, 3))

                    thisbuf = Buffer(self, self.verts, self.texcoords,
                                     self.inds, self.norms)
                    if not isinstance(textures[j][i],
                                      Texture):  # i.e. can load from file name
                        textures[j][i] = Texture(textures[j][i])
                    thisbuf.textures = [textures[j][i]]
                    self.buf.append(thisbuf)
            self.set_shader(shader)
            self.set_2d_size()  # method in Shape, default full window size
        except IndexError:
            print('Must supply a list of lists of Textures or strings')
            return
Ejemplo n.º 3
0
  def merge(self, bufr, x=0.0, y=0.0, z=0.0,
            rx=0.0, ry=0.0, rz=0.0,
            sx=1.0, sy=1.0, sz=1.0, bufnum=0):
    """merge the vertices, normals etc from this Buffer with those already there
    the position, rotation, scale, offset are set according to the origin of
    the MergeShape. If bufr is not a Buffer then it will be treated as if it
    is a Shape and its first Buffer object will be merged. Argument additional
    to standard Shape:

      *bufr*
        Buffer object or Shape with a member buf[0] that is a Buffer object.
        OR an array or tuple where each element is an array or tuple with
        the required arguments i.e. [[bufr1, x1, y1, z1, rx1, ry1....],
        [bufr2, x2, y2...],[bufr3, x3, y3...]] this latter is a more efficient
        way of building a MergeShape from lots of elements. If multiple
        Buffers are passed in this way then the subsequent arguments (x,y,z etc)
        will be ignored.
        
      *x, y, z, rx, ry, rz, sx, sy, sz*
        Position rotation scale if merging a single Buffer
      
      *bufnum*
        Specify the index of Buffer to use. This allows a MergeShape to
        contain multiple Buffers each with potentially different shader,
        material, textures, draw_method and unib
    """
    if not isinstance(bufr, list) and not isinstance(bufr, tuple):
      buflist = [[bufr, x, y, z, rx, ry, rz, sx, sy, sz, bufnum]]
    else:
      buflist = bufr

    # existing array and element buffers to add to (as well as other draw relevant values)
    vertices = [] # will hold a list of ndarrays - one for each Buffer
    normals = []
    tex_coords = []
    indices = []
    shader_list = []
    material_list = []
    textures_list = []
    draw_method_list = []
    unib_list = []
    for b in self.buf: # first of all collect info from pre-existing Buffers
      buf = b.array_buffer# alias to tidy code
      vertices.append(buf[:,0:3] if len(buf) > 0 else buf)
      normals.append(buf[:,3:6] if len(buf) > 0 else buf)
      tex_coords.append(buf[:,6:8] if len(buf) > 0 else buf) #TODO this will only cope with N_BYTES == 32
      indices.append(b.element_array_buffer[:])
      shader_list.append(b.shader)
      material_list.append(b.material[:])
      textures_list.append(b.textures[:])
      draw_method_list.append(b.draw_method)
      unib_list.append(b.unib[:])

    for b in buflist:
      if len(b) < 11:
        b.append(0)
      if b[10] >= len(vertices): #add buffers if needed
        for i in range(b[10] - len(vertices) + 1):
          vertices.append(np.zeros((0, 3), dtype='float32'))
          tex_coords.append(np.zeros((0, 2), dtype='float32'))
          indices.append(np.zeros((0, 3), dtype='float32'))
          normals.append(np.zeros((0, 3), dtype='float32'))
          shader_list.append(None)
          material_list.append(())
          textures_list.append([])
          draw_method_list.append(None)
          unib_list.append([])
      if not(type(b[0]) is Buffer): #deal with being passed a Shape
        bufr = b[0].buf[0]
      else:
        bufr = b[0]

      n = len(bufr.array_buffer)

      LOGGER.info("Merging Buffer %s", bufr)

      original_vertex_count = len(vertices[b[10]])

      vrot = rotate_vec(b[4], b[5], b[6], np.array(bufr.array_buffer[:,0:3]))
      vrot[:,0] = vrot[:,0] * b[7] + b[1]
      vrot[:,1] = vrot[:,1] * b[8] + b[2]
      vrot[:,2] = vrot[:,2] * b[9] + b[3]
      if bufr.array_buffer.shape[1] >= 6:
        nrot = rotate_vec(b[4], b[5], b[6], np.array(bufr.array_buffer[:,3:6]))
      else:
        nrot = np.zeros((n, 3))

      vertices[b[10]] = np.append(vertices[b[10]], vrot)
      normals[b[10]] = np.append(normals[b[10]], nrot)
      if bufr.array_buffer.shape[1] == 8:
        tex_coords[b[10]] = np.append(tex_coords[b[10]], bufr.array_buffer[:,6:8])
      else:
        tex_coords[b[10]] = np.append(tex_coords[b[10]], np.zeros((n, 2)))

      n = int(len(vertices[b[10]]) / 3)
      vertices[b[10]].shape = (n, 3)
      normals[b[10]].shape = (n, 3)
      tex_coords[b[10]].shape = (n, 2)

      #ctypes.restype = ctypes.c_short  # TODO: remove this side-effect.
      faces = bufr.element_array_buffer + original_vertex_count
      indices[b[10]] = np.append(indices[b[10]], faces)

      n = int(len(indices[b[10]]) / 3)
      indices[b[10]].shape = (n, 3)

      shader_list[b[10]] = bufr.shader
      material_list[b[10]] = bufr.material[:]
      textures_list[b[10]] = bufr.textures[:]
      draw_method_list[b[10]] = bufr.draw_method
      unib_list[b[10]] = bufr.unib[:]

    self.buf = []
    for i in range(len(vertices)):
      buf = Buffer(self, vertices[i], tex_coords[i], indices[i], normals[i])
      # add back Buffer details from lists
      buf.shader = shader_list[i]
      buf.material = material_list[i]
      buf.textures = textures_list[i]
      buf.draw_method = draw_method_list[i]
      for j in range(len(unib_list[i])): # have to change elements in ctypes array
        buf.unib[j] = unib_list[i][j]
      self.buf.append(buf)