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, camera=None, light=None, name="", z=0.1):
    """Uses standard constructor for Shape but only one position variable is
    available as Keyword argument:

      *z*
        The depth that the shape will be constructed as an actual z offset
        distance in the vertices. As the Canvas is intended for use with
        2d shaders there is no way to change its location as no matrix
        multiplication will happen in the vertex shader.
    """
    super(Canvas, self).__init__(camera, light, name, 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, 
                                cx=0.0, cy=0.0, cz=0.0)
    self.ttype = GL_TRIANGLES
    self.verts = []
    self.norms = []
    self.texcoords = []
    self.inds = []
    self.depth = z

    ww = 20.0
    hh = 20.0

    self.verts = ((-ww, -hh, z), (0.0, hh, z), (ww, -hh, z))
    self.norms = ((0, 0, -1), (0, 0, -1),  (0, 0, -1))
    self.texcoords = ((0.0, 0.0), (0.5, 1.0), (1.0, 0.0))

    self.inds = ((0, 1, 2), ) #python quirk: comma for tuple with only one val

    self.buf = []
    self.buf.append(Buffer(self, self.verts, self.texcoords, self.inds, self.norms))
Ejemplo n.º 3
0
  def __init__(self, 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, flip=False):
    """Uses standard constructor for Shape. Extra Keyword arguments:

      *w*
        Width.
      *h*
        Height.
      *flip*
        If set to True then the Sprite is flipped vertically (top to bottom)
    """
    super(Sprite, 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
    hh = h / 2.0 if not flip else -h / 2.0

    self.verts = ((-ww, hh, 0.0), (ww, hh, 0.0), (ww, -hh, 0.0), (-ww, -hh, 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)) if not flip else ((3, 2, 0), (2, 1, 0))

    self.buf = []
    self.buf.append(Buffer(self, self.verts, self.texcoords, self.inds, self.norms))
Ejemplo n.º 4
0
    def __init__(self,
                 camera=None,
                 light=None,
                 name="",
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """uses standard constructor for Shape"""
        super(MergeShape, self).__init__(camera, light, name, x, y, z, rx, ry,
                                         rz, sx, sy, sz, cx, cy, cz)

        LOGGER.info("Creating Merge Shape ...")

        self.buf = [
            Buffer(self, [], [], [], [])
        ]  # create single empty buffer in case draw() before first merge()
        self.childModel = None  #unused but asked for by pickle
    def __init__(self,
                 camera=None,
                 light=None,
                 name="",
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """uses standard constructor for Shape"""
        super(MergeShape, self).__init__(camera, light, name, x, y, z, rx, ry,
                                         rz, sx, sy, sz, cx, cy, cz)

        LOGGER.info("Creating Merge Shape ...")

        self.buf = [
            Buffer(self, [], [], [], [])
        ]  # create single empty buffer in case draw() before first merge()
        self.billboard_array = [
            np.zeros((0, 6), dtype='float32')
        ]  # list of arrays holding x0, z0, x, z, nx, nz for each vert
        self.childModel = None  #unused but asked for by pickle
  def __init__(self,  camera=None, light=None, name="", 
                corners=((-1.0, -0.57735, -0.57735),
                         (1.0, -0.57735, -0.57735),
                         (0.0, -0.57735, 1.15470),
                         (0.0, 1.15470, 0.0)),
                x=0.0, y=0.0, z=0.0, sx=1.0, sy=1.0, sz=1.0,
                rx=0.0, ry=0.0, rz=0.0, cx=0.0, cy=0.0, cz=0.0):
    """Uses standard constructor for Shape with ability to position corners.
    The uv mapping is taken from four equilateral triangles arranged on a
    square forming an upwards pointing arrow ^. Starting at the left bottom
    corner of the image the first three triangles are unwrapped from around
    the top of the tetrahedron and the right bottom triangle is the base
    (if the corners are arranged as per the default) Keyword argument:

      *corners*
        A tuple of four (xyz) tuples defining the corners
    """
    super(Tetrahedron, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                sx, sy, sz, cx, cy, cz)
    c = corners # alias
    verts = (c[0], c[3], c[1], c[2], c[3], c[0],
                  c[1], c[3], c[2], c[0], c[1], c[2])
    texcoords = ((0.0, 0.0), (0.0, 0.57735), (0.5, 0.288675),
                      (0.0, 0.57735), (0.5, 0.866025), (0.5, 0.288675),
                      (0.5, 0.866025), (1.0, 0.57735), (0.5, 0.288675),
                      (0.5, 0.288675), (1.0, 0.57735), (1.0, 0.0))
    inds = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11))

    self.buf = [Buffer(self, verts, texcoords, inds, normals=None, smooth=False)]
Ejemplo n.º 7
0
    def __init__(self,
                 camera=None,
                 light=None,
                 name="",
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """uses standard constructor for Shape"""
        super(MergeShape, self).__init__(camera, light, name, x, y, z, rx, ry,
                                         rz, sx, sy, sz, cx, cy, cz)

        if VERBOSE:
            print "Creating Merge Shape ..."

        self.vertices = []
        self.normals = []
        self.tex_coords = []
        self.indices = []  #stores all indices for single render

        self.buf = []
        self.buf.append(
            Buffer(self, self.vertices, self.tex_coords, self.indices,
                   self.normals))
Ejemplo n.º 8
0
    def __init__(self,
                 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,
                 flip=True):
        """Uses standard constructor for Shape. Extra Keyword arguments:

      *w*
        Width.
      *h*
        Height.
      *flip* Should the image be flipped over
    """
        #super(FlipSprite, self).super(Sprite, self).
        sprt = super(FlipSprite, self)
        super(Sprite, 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

        ###...
        hh = h / 2.0 if not flip else -h / 2.0
        #    hh = h / 2.0

        self.verts = ((-ww, hh, 0.0), (ww, hh, 0.0), (ww, -hh, 0.0), (-ww, -hh,
                                                                      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)) if not flip else ((3, 2, 0), (2, 1,
                                                                         0))
        #    self.inds = ((0, 1, 3), (1, 2, 3))

        self.buf = []
        self.buf.append(
            Buffer(self, self.verts, self.texcoords, self.inds, self.norms))
Ejemplo n.º 9
0
Archivo: Disk.py Proyecto: wildone/pi3d
    def __init__(self,
                 camera=None,
                 light=None,
                 radius=1,
                 sides=12,
                 name="",
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """uses standard constructor for Shape extra Keyword arguments:

      *radius*
        Radius of disk.
      *sides*
        Number of sides to polygon representing disk.
    """
        super(Disk, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                   sx, sy, sz, cx, cy, cz)

        if VERBOSE:
            print("Creating disk ...")

        self.verts = []
        self.norms = []
        self.inds = []
        self.texcoords = []
        self.ttype = GL_TRIANGLES
        self.sides = sides

        st = 2 * pi / sides
        for j in range(-1, 1):
            self.verts.append((0.0, -0.1 * j, 0.0))
            self.norms.append((0.0, -j, 0.0))
            self.texcoords.append((0.5, 0.5))
            for r in range(sides + 1):
                ca, sa = Utility.from_polar_rad(r * st)
                self.verts.append((radius * sa, 0.0, radius * ca))
                self.norms.append((0.0, -j - 0.1 * j, 0.0))
                self.texcoords.append((sa * 0.5 + 0.5, ca * 0.5 + 0.5))
            if j == -1:
                v0, v1, v2 = 0, 1, 2
            else:
                v0, v1, v2 = sides + 2, sides + 4, sides + 3  # i.e. reverse direction to show on back
            for r in range(sides):
                self.inds.append((v0, r + v1, r + v2))

        self.but = []
        self.buf.append(
            Buffer(self, self.verts, self.texcoords, self.inds, self.norms))
Ejemplo n.º 10
0
    def __init__(self,
                 camera=None,
                 light=None,
                 w=1.0,
                 h=1.0,
                 name="",
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """uses standard constructor for Shape extra Keyword arguments:

      *w*
        width
      *h*
        height
    """
        super(Plane, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                    sx, sy, sz, cx, cy, cz)

        if VERBOSE:
            print("Creating plane ...")

        self.width = w
        self.height = h
        self.ttype = GL_TRIANGLES
        self.verts = []
        self.norms = []
        self.texcoords = []
        self.inds = []

        ww = w / 2.0
        hh = h / 2.0

        self.verts = ((-ww, hh, 0.0), (ww, hh, 0.0), (ww, -hh, 0.0),
                      (-ww, -hh, 0.0), (-ww, hh, 0.0), (ww, hh, 0.0),
                      (ww, -hh, 0.0), (-ww, -hh, 0.0))
        self.norms = ((0.0, 0.0, -1), (0.0, 0.0, -1), (0.0, 0.0, -1),
                      (0.0, 0.0, -1), (0.0, 0.0, 1), (0.0, 0.0, 1),
                      (0.0, 0.0, 1), (0.0, 0.0, 1))
        self.texcoords = ((0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0),
                          (0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0))

        self.inds = ((0, 1, 3), (1, 2, 3), (5, 4, 7), (6, 5, 7))

        self.buf = []
        self.buf.append(
            Buffer(self, self.verts, self.texcoords, self.inds, self.norms))
Ejemplo n.º 11
0
    def __init__(self,
                 camera=None,
                 light=None,
                 inner=0.5,
                 outer=1,
                 sides=12,
                 name="",
                 start=0.0,
                 end=60,
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """Slice with outer and inner radius. NB this is in the xy plane rather than the
    xz plane that Disk produces and is only one sided. It uses standard constructor
    for Shape extra with the following Keyword arguments:

      *inner*
        Inner radius of slice.
      *outer*
        Outer radius.
      *sides*
        Number of sides on outside and inside of polygon.
      *start*
        Angle in degrees clockwise from vertical up, to start slice.
      *end*
        Angle to end slice.
    """
        super(Slice, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                    sx, sy, sz, cx, cy, cz)

        LOGGER.debug("Creating slice ...")

        self.inner = inner
        self.outer = outer
        self.start = start
        self.end = end
        self.n = sides + 1
        (verts, texcoords) = self.make_verts()
        norms = np.zeros_like(verts)
        norms[:, 2] = -1.0
        inds = np.array([[2 * i + u, 2 * i + v, 2 * i + w]
                         for i in range(0, sides)
                         for (u, v, w) in [(0, 1, 3), (3, 2, 0)]],
                        dtype=int)
        verts[:, 2] = z
        self.buf = [Buffer(self, verts, texcoords, inds, norms)]
Ejemplo n.º 12
0
    def __init__(self,
                 camera=None,
                 light=None,
                 vertices=[],
                 material=(1.0, 1.0, 1.0),
                 line_width=1,
                 closed=False,
                 name="",
                 x=0.0,
                 y=0.0,
                 z=0.0,
                 sx=1.0,
                 sy=1.0,
                 sz=1.0,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0,
                 strip=True):
        """uses standard constructor for Shape extra Keyword arguments:

      *vertices*
        array of tuples [(x0,y0,z0),(x1,y1,z1)..]
      *material*
        tuple (r,g,b)
      *line_width*
        set to 1 if absent or set to a value less than 1
      *closed*
        joins up last leg i.e. for polygons
      *strip*
        use GL_LINE_STRIP otherwise GL_LINES - needs pairs for line ends
    """
        super(Lines, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                    sx, sy, sz, cx, cy, cz)

        LOGGER.info("Creating Lines ...")

        n_v = len(vertices)
        indices = [[a, a + 1, a + 2] for a in range(0, n_v, 3)]
        for i in range(1, 3):
            last = indices[-1]
            if last[i] >= n_v:
                last[i] = n_v - 1

        self.buf = [Buffer(self, vertices, [], indices, [], smooth=False)]

        if line_width < 1:
            self.set_line_width(1, closed)
        else:
            self.set_line_width(line_width=line_width,
                                closed=closed,
                                strip=strip)
        self.set_material(material)
Ejemplo n.º 13
0
    def __init__(self,
                 camera=None,
                 light=None,
                 vertices=[],
                 material=(1.0, 1.0, 1.0),
                 point_size=1,
                 name="",
                 x=0.0,
                 y=0.0,
                 z=0.0,
                 sx=1.0,
                 sy=1.0,
                 sz=1.0,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0,
                 normals=[],
                 tex_coords=[]):
        """uses standard constructor for Shape extra Keyword arguments:

      *vertices*
        array of tuples [(x0,y0,z0),(x1,y1,z1)..]
      *material*
        tuple (r,g,b)
      *point_size*
        set to 1 if absent or set to a value less than 1
    """
        super(Points, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                     sx, sy, sz, cx, cy, cz)

        LOGGER.info("Creating Points ...")

        n_v = len(vertices)
        indices = [[a, a + 1, a + 2] for a in range(0, n_v, 3)]
        for i in range(1, 3):
            last = indices[-1]
            if last[i] >= n_v:
                last[i] = n_v - 1
        if normals == [] and tex_coords == []:
            normals = [[0.0, 0.0, 0.0]
                       for i in range(n_v)]  #used for rgb in mat_pointsprite
            tex_coords = [[1.0, 0.0] for i in range(n_v)
                          ]  # [:,0] used for alpha in mat_pointsprite
        self.buf = [
            Buffer(self, vertices, tex_coords, indices, normals, smooth=False)
        ]

        if point_size < 1:
            self.set_point_size(1)
        else:
            self.set_point_size(point_size)
        self.set_material(material)
Ejemplo n.º 14
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):
    """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.
    """
    if not isinstance(bufr, list) and not isinstance(bufr, tuple):
      buflist = [[bufr, x, y, z, rx, ry, rz, sx, sy, sz]]
    else:
      buflist = bufr

    for b in buflist:
      if not(type(b[0]) is Buffer):
        bufr = b[0].buf[0]
      else:
        bufr = b[0]

      #assert shape.ttype == GL_TRIANGLES # this is always true of Buffer objects
      assert len(bufr.vertices) == len(bufr.normals)

      if VERBOSE:
        print("Merging", bufr.name)

      original_vertex_count = len(self.vertices)

      for v in range(0, len(bufr.vertices)):
        # Scale, offset and store vertices
        vx, vy, vz = rotate_vec(b[4], b[5], b[6], bufr.vertices[v])
        self.vertices.append((vx * b[7] + b[1], vy * b[8] + b[2], vz * b[9] + b[3]))

        # Rotate normals
        self.normals.append(rotate_vec(b[4], b[5], b[6], bufr.normals[v]))

      self.tex_coords.extend(bufr.tex_coords)

      ctypes.restype = ctypes.c_short  # TODO: remove this side-effect.
      indices = [(i[0] + original_vertex_count, i[1] + original_vertex_count,
                  i[2] + original_vertex_count) for i in bufr.indices]
      self.indices.extend(indices)

    self.buf = []
    self.buf.append(Buffer(self, self.vertices, self.tex_coords, self.indices, self.normals))
Ejemplo n.º 15
0
    def __init__(self,
                 camera=None,
                 light=None,
                 vertices=[],
                 material=(1.0, 1.0, 1.0),
                 point_size=1,
                 name="",
                 x=0.0,
                 y=0.0,
                 z=0.0,
                 sx=1.0,
                 sy=1.0,
                 sz=1.0,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """uses standard constructor for Shape extra Keyword arguments:

      *vertices*
        array of tuples [(x0,y0,z0),(x1,y1,z1)..]
      *material*
        tuple (r,g,b)
      *point_size*
        set to 1 if absent or set to a value less than 1
    """
        super(Points, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                     sx, sy, sz, cx, cy, cz)

        if VERBOSE:
            print("Creating Points ...")

        self.vertices = vertices
        self.normals = []
        n_v = len(vertices)
        self.indices = [(a, a + 1, a + 2) for a in range(0, n_v, 3)]
        self.tex_coords = []
        self.buf = [
            Buffer(self,
                   self.vertices,
                   self.tex_coords,
                   self.indices,
                   self.normals,
                   smooth=False)
        ]

        if point_size < 1:
            self.set_point_size(1)
        else:
            self.set_point_size(point_size)
        self.set_material(material)
Ejemplo n.º 16
0
  def merge(self, bufr, x, y, z,
            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):
    """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.
    """
    if not(type(bufr) is Buffer):
      bufr = bufr.buf[0]

    #assert shape.ttype == GL_TRIANGLES # this is always true of Buffer objects
    assert len(bufr.vertices) == len(bufr.normals)

    if VERBOSE:
      print "Merging", bufr.name

    vertices = []
    normals = []
    original_vertex_count = len(self.vertices)

    for v in range(0, len(bufr.vertices)):
      def rotate_slice(array):
        vec = array[v]
        if rz:
          vec = rotate_vec_z(rz, vec)
        if rx:
          vec = rotate_vec_x(rx, vec)
        if ry:
          vec = rotate_vec_y(ry, vec)
        return vec

      # Scale, offset and store vertices
      vx, vy, vz = rotate_slice(bufr.vertices)
      self.vertices.append((vx * sx + x, vy * sy + y, vz * sz + z))

      # Rotate normals
      self.normals.append(rotate_slice(bufr.normals))

    self.tex_coords.extend(bufr.tex_coords)

    ctypes.restype = ctypes.c_short  # TODO: remove this side-effect.
    indices = [(i[0] + original_vertex_count, i[1] + original_vertex_count, i[2] + original_vertex_count) for i in bufr.indices]
    self.indices.extend(indices)

    self.buf = []
    self.buf.append(Buffer(self, self.vertices, self.tex_coords, self.indices, self.normals))
Ejemplo n.º 17
0
    def __init__(self,
                 camera=None,
                 light=None,
                 radius=1,
                 sides=12,
                 name="",
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """uses standard constructor for Shape extra Keyword arguments:

      *radius*
        Radius of disk.
      *sides*
        Number of sides to polygon representing disk.
    """
        super(RoundCorner, self).__init__(camera, light, name, x, y, z, rx, ry,
                                          rz, sx, sy, sz, cx, cy, cz)

        verts = []
        norms = []
        inds = []
        texcoords = []
        self.sides = sides

        st = (pi / 2) / sides
        for j in range(-1, 1):
            verts.append((0.0, -0.1 * j, 0.0))
            norms.append((0.0, -j, 0.0))
            texcoords.append((0.5, 0.5))
            for r in range(0, sides + 1):
                ca, sa = Utility.from_polar_rad(r * st)
                verts.append((radius * sa, 0.0, radius * ca))
                norms.append((0.0, -j - 0.1 * j, 0.0))
                texcoords.append((sa * 0.5 + 0.5, ca * 0.5 + 0.5))
            if j == -1:
                v0, v1, v2 = 0, 1, 2
            else:
                v0, v1, v2 = sides + 2, sides + 4, sides + 3  # i.e. reverse direction to show on back
            for r in range(sides):
                inds.append((v0, r + v1, r + v2))

        self.buf = [Buffer(self, verts, texcoords, inds, norms)]
Ejemplo n.º 18
0
  def __init__(self, camera=None, light=None, font=None, string=None,
               x=0.0, y=0.0, z=1.0,
               sx=DEFAULT_FONT_SCALE, sy=DEFAULT_FONT_SCALE,
               is_3d=True, size=DEFAULT_FONT_DOT_SIZE,
               rx=0.0, ry=0.0, rz=0.0):
    """Standard Shape constructor without the facility to change z scale or 
    any of the offset values. Additional keyword arguments:
    
      *font*
        Font or Ttffont class object.
      *string*
        of ASCI characters in range(32, 128)
    """
    if not is_3d:
      sy = sx = size / DOTS_PER_INCH
    super(String, self).__init__(camera, light, "", x, y, z,
                                 rx, ry, rz,  sx, sy, 1.0,  0.0, 0.0, 0.0)

    if VERBOSE:
      print "Creating string ..."

    self.verts = []
    self.texcoords = []
    self.norms = []
    self.inds = []
    temp_verts = []

    xoff = 0.0
    maxh = 0.0
    #TODO cope with \n characters to give multi line strings
    for i, c in enumerate(string):
      v = ord(c) - 32
      w, h, texc, verts = font.ch[v]
      if v >= 0:
        for j in verts:
          temp_verts.append((j[0]+xoff, j[1], j[2]))
        xoff += w
        if h > maxh: maxh = h
        for j in texc: self.texcoords.append(j)
        for j in [(0.0,0.0,1.0), (0.0,0.0,1.0), (0.0,0.0,1.0), (0.0,0.0,1.0)]: self.norms.append(j)
        stv = 4 * i
        for j in [(stv, stv + 2, stv + 1), (stv, stv + 3, stv + 2)]: self.inds.append(j)

    for j in temp_verts:
      self.verts.append((j[0] - xoff/2.0, j[1] + maxh/2.0, j[2]))

    self.buf = []
    self.buf.append(Buffer(self, self.verts, self.texcoords, self.inds, self.norms))
    self.buf[0].textures = [font]
    self.buf[0].unib[1] = -1.0
Ejemplo n.º 19
0
    def __init__(self,
                 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. Extra Keyword arguments:

      *w*
        Width.
      *h*
        Height.
    """
        super(Sprite, 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
        hh = h / 2.0

        self.verts = ((-ww, hh, 0.0), (ww, hh, 0.0), (ww, -hh, 0.0), (-ww, -hh,
                                                                      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))

        self.buf = []
        self.buf.append(
            Buffer(self, self.verts, self.texcoords, self.inds, self.norms))
Ejemplo n.º 20
0
    def __init__(self,
                 camera=None,
                 light=None,
                 w=1.0,
                 h=1.0,
                 name="",
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """uses standard constructor for Shape extra Keyword arguments:

      *w*
        width
      *h*
        height
    """
        super(Plane, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                    sx, sy, sz, cx, cy, cz)

        LOGGER.info("Creating plane ...")

        self.width = w
        self.height = h

        ww = w / 2.0
        hh = h / 2.0

        verts = ((-ww, hh, 0.0), (ww, hh, 0.0), (ww, -hh, 0.0),
                 (-ww, -hh, 0.0), (-ww, hh, 0.0), (ww, hh, 0.0),
                 (ww, -hh, 0.0), (-ww, -hh, 0.0))
        norms = ((0.0, 0.0, -1), (0.0, 0.0, -1), (0.0, 0.0, -1), (0.0, 0.0,
                                                                  -1),
                 (0.0, 0.0, 1), (0.0, 0.0, 1), (0.0, 0.0, 1), (0.0, 0.0, 1))
        texcoords = ((0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0),
                     (0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0))

        inds = ((3, 0, 1), (1, 2, 3), (7, 6, 5), (5, 4, 7))

        self.buf = [Buffer(self, verts, texcoords, inds, norms)]
Ejemplo n.º 21
0
    def __init__(self,
                 camera=None,
                 light=None,
                 name="",
                 corners=((-0.5, -0.28868), (0.0, 0.57735), (0.5, -0.28868)),
                 x=0.0,
                 y=0.0,
                 z=0.0,
                 sx=1.0,
                 sy=1.0,
                 sz=1.0,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """Uses standard constructor for Shape with ability to position corners.
    The corners must be arranged clockwise (for the Triangle to face -z direction)
    The uv mapping is taken from an equilateral triangles base 0,0 to 1,0
    peak at 0.5, 0.86603 Keyword argument:

      *corners*
        A tuple of three (xy) tuples defining the corners
    """
        super(Triangle, self).__init__(camera, light, name, x, y, z, rx, ry,
                                       rz, sx, sy, sz, cx, cy, cz)
        self.ttype = GL_TRIANGLES
        self.verts = []
        self.norms = []
        self.texcoords = []
        self.inds = []
        c = corners  # alias for convenience

        self.verts = ((c[0][0], c[0][1], 0.0), (c[1][0], c[1][1], 0.0),
                      (c[2][0], c[2][1], 0.0))
        self.norms = ((0, 0, -1), (0, 0, -1), (0, 0, -1))
        self.texcoords = ((0.0, 0.0), (0.5, 0.86603), (1.0, 0.0))

        self.inds = ((0, 1, 2),
                     )  #python quirk: comma for tuple with only one val

        self.buf = []
        self.buf.append(
            Buffer(self, self.verts, self.texcoords, self.inds, self.norms))
Ejemplo n.º 22
0
    def __init__(self,
                 camera=None,
                 light=None,
                 name="",
                 corners=((-0.5, -0.28868), (0.0, 0.57735), (0.5, -0.28868)),
                 x=0.0,
                 y=0.0,
                 z=0.0,
                 sx=1.0,
                 sy=1.0,
                 sz=1.0,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """Uses standard constructor for Shape with ability to position corners.
    The corners must be arranged clockwise (for the Triangle to face -z direction)

    Keyword argument:

      *corners*
        A tuple of three (xy) tuples defining the corners
    """
        super(Triangle, self).__init__(camera, light, name, x, y, z, rx, ry,
                                       rz, sx, sy, sz, cx, cy, cz)
        c = corners  # alias for convenience

        verts = ((c[0][0], c[0][1], 0.0), (c[1][0], c[1][1], 0.0),
                 (c[2][0], c[2][1], 0.0))
        norms = ((0, 0, -1), (0, 0, -1), (0, 0, -1))
        maxx = max(v[0] for v in corners)  # u,v to match vertex locations
        minx = min(v[0] for v in corners)
        xscale = 1.0 / (maxx - minx)
        maxy = max(v[1] for v in corners)
        miny = min(v[1] for v in corners)
        yscale = 1.0 / (maxy - miny)
        texcoords = [((v[0] - minx) * xscale, 1.0 - (v[1] - miny) * yscale)
                     for v in verts]

        inds = ((0, 1, 2), )  #python quirk: comma for tuple with only one val

        self.buf = [Buffer(self, verts, texcoords, inds, norms)]
Ejemplo n.º 23
0
  def __init__(self, camera=None, light=None, name="",
               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,
               cx=0.0, cy=0.0, cz=0.0):
    """uses standard constructor for Shape"""
    super(MergeShape, self).__init__(camera, light, name, x, y, z,
                                   rx, ry, rz, sx, sy, sz, cx, cy, cz)

    LOGGER.info("Creating Merge Shape ...")

    self.vertices = []
    self.normals = []
    self.tex_coords = []
    self.indices = []    #stores all indices for single render

    self.buf = []
    self.buf.append(Buffer(self, self.vertices, self.tex_coords, self.indices, self.normals))
    self.childModel = None #unused but asked for by pickle
Ejemplo n.º 24
0
    def create_mesh_buffer(self):

        ww = self.width / 2.0
        hh = self.height / 2.0
        nx, ny = self.mesh_size

        verts = []
        texcoords = []
        inds = []

        for x in range(nx + 1):
            for y in range(ny + 1):
                coords = (-ww + self.width / nx * x, hh - self.height / ny * y, 0.0)
                verts.append(coords)
                texcoords.append(((coords[0] + ww) / self.width, -(coords[1] - hh) / self.height))

        for y in range(ny):
            for x in range(nx):
                a = y + (ny + 1) * x
                b = a + 1
                c = y + (ny + 1) * (x + 1)
                inds.append((a, b, c))

                a = y + (ny + 1) * (x + 1)
                # b = b
                c = a + 1
                inds.append((a, b, c))

        # for wireframe mode
        topright = nx * (ny + 1)
        bottomright = (nx + 1) * (ny + 1) - 1
        inds.append((bottomright, topright, topright))

        new_buffer = Buffer(self, verts, texcoords, inds, None)

        if self.buf:
            old_buffer = self.buf[0]
            new_buffer.set_material(old_buffer.unib[3:6])
            new_buffer.set_textures(old_buffer.textures)
            new_buffer.shader = old_buffer.shader

        self.buf = [new_buffer]

        if self.mesh_debug:
            self.set_mesh_debug(self.mesh_debug)
Ejemplo n.º 25
0
    def _lathe(self, path, sides=12, rise=0.0, loops=1.0):
        """Returns a Buffer object by rotating the points defined in path.

    Arguments:
      *path*
        An array of points [(x0, y0), (x1, y1) ...] to rotate around
        the y axis.

    Keyword arguments:
      *sides*
        Number of sides to divide each rotation into.
      *rise*
        Amount to increment the path y values for each rotation (ie helix)
      *loops*
        Number of times to rotate the path by 360 (ie helix).

    """
        self.sides = sides

        s = len(path)
        rl = int(self.sides * loops)

        pn = 0
        pp = 0
        tcx = 1.0 / self.sides
        pr = (pi / self.sides) * 2.0
        rdiv = rise / rl

        # Find largest and smallest y of the path used for stretching the texture
        miny = path[0][1]
        maxy = path[s - 1][1]
        for p in range(s):
            if path[p][1] < miny:
                miny = path[p][1]
            if path[p][1] > maxy:
                maxy = path[p][1]

        verts = []
        norms = []
        idx = []
        tex_coords = []

        opx = path[0][0]
        opy = path[0][1]

        for p in range(s):

            px = path[p][0] * 1.0
            py = path[p][1] * 1.0

            tcy = 1.0 - ((py - miny) / (maxy - miny))

            # Normalized 2D vector between path points
            dx, dy = Utility.vec_normal(Utility.vec_sub((px, py), (opx, opy)))

            for r in range(0, rl):
                sinr = sin(pr * r)
                cosr = cos(pr * r)
                verts.append((px * sinr, py, px * cosr))
                norms.append((-sinr * dy, dx, -cosr * dy))
                tex_coords.append((1.0 - tcx * r, tcy))
                py += rdiv

            # Last path profile (tidies texture coords).
            verts.append((0, py, px))
            norms.append((0, dx, -dy))
            tex_coords.append((0, tcy))

            if p < s - 1:
                pn += (rl + 1)
                for r in range(rl):
                    idx.append((pp + r + 1, pp + r, pn + r))
                    idx.append((pn + r, pn + r + 1, pp + r + 1))
                pp += (rl + 1)

            opx = px
            opy = py

        return Buffer(self, verts, tex_coords, idx, norms)
Ejemplo n.º 26
0
    def __init__(self,
                 mapfile,
                 camera=None,
                 light=None,
                 width=100.0,
                 depth=100.0,
                 height=10.0,
                 divx=0,
                 divy=0,
                 ntiles=1.0,
                 name="",
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0,
                 smooth=True,
                 cubic=False):
        """uses standard constructor for Shape

    Arguments:
      *mapfile*
        Greyscale image path/file, string. If multiple bytes per pixel
        only the first one will be used for elevation. jpg files will
        create slight errors that will cause mis-matching of edges for
        tiled maps (i.e. use png for these) NB also see divx, divy below
        i.e. div=64x64 requires image 65x65 pixels 

    Keyword arguments:
      *width, depth, height*
        Of the map in world units.
      *divx, divy*
        Number of divisions into which the map will be divided.
        to create vertices (vertices += 1) NB if you want to create a map
        with 64x64 divisions there will be 65x65 vertices in each direction so
        the mapfile (above) needs to 65x65 pixels in order to specify
        elevations precisely and avoid resizing errors.
      *ntiles*
        Number of repeats for tiling the texture image.
      *smooth*
        Calculate normals with averaging rather than pointing
        straight up, slightly faster if false.
    """
        super(ElevationMap, self).__init__(camera, light, name, x, y, z, rx,
                                           ry, rz, sx, sy, sz, cx, cy, cz)
        divx += 1  # one more vertex in each direction than number of divisions
        divy += 1
        if divx > 200 or divy > 200:
            print("... Map size can't be bigger than 199x199 divisions")
            divx = 200
            divy = 200
        #print(type(mapfile), type(""))

        try:
            if '' + mapfile == mapfile:  #HORRIBLE. Only way to cope with python2v3
                if mapfile[0] != '/':
                    for p in sys.path:
                        if os.path.isfile(
                                p + '/' + mapfile
                        ):  # this could theoretically get different files with same name
                            mapfile = p + '/' + mapfile
                            break
                if VERBOSE:
                    print("Loading height map ...", mapfile)

                im = Image.open(mapfile)
            else:
                im = mapfile  #allow image files to be passed as mapfile
        except:
            im = mapfile
        ix, iy = im.size
        if (ix > 200 and divx == 0) or (ix != divx and iy != divy):
            if divx == 0:
                divx = 200
                divy = 200
            im = im.resize((divx, divy), Image.ANTIALIAS)
            ix, iy = im.size

        im = im.transpose(Image.FLIP_TOP_BOTTOM)
        im = im.transpose(Image.FLIP_LEFT_RIGHT)
        self.pixels = im.load()
        self.width = width
        self.depth = depth
        self.height = height
        self.ix = ix
        self.iy = iy
        self.ttype = GL_TRIANGLE_STRIP

        if VERBOSE:
            print("Creating Elevation Map ...", ix, iy)

        wh = width * 0.5
        hh = depth * 0.5
        ws = width / (ix - 1.0)
        hs = depth / (iy - 1.0)
        ht = height / 255.0
        tx = 1.0 * ntiles / ix
        ty = 1.0 * ntiles / iy

        verts = []
        norms = []
        tex_coords = []
        idx = []

        for y in xrange(0, iy):
            for x in xrange(0, ix):
                pxl = self.pixels[x, y]
                hgt = pxl[0] if type(pxl) is tuple else pxl
                hgt *= ht
                this_x = -wh + x * ws
                this_z = -hh + y * hs
                if cubic:
                    """ this is a bit experimental. It tries to make the map either zero
          or height high. Vertices are moved 'under' adjacent ones if there is
          a step to make vertical walls. Goes wrong in places - mainly because
          it doesn't check diagonals
          """
                    if hgt > height / 2:
                        hgt = height
                    else:
                        hgt = 0.0
                    if hgt == 0 and y > 0 and y < iy - 1 and x > 0 and x < ix - 1:
                        if self.pixels[x - 1, y] > 127:
                            this_x = -wh + (x - 1) * ws
                        elif self.pixels[x + 1, y] > 127:
                            this_x = -wh + (x + 1) * ws
                        elif self.pixels[x, y - 1] > 127:
                            this_z = -hh + (y - 1) * hs
                        elif self.pixels[x, y + 1] > 127:
                            this_z = -hh + (y + 1) * hs
                        elif self.pixels[x - 1, y - 1] > 127:
                            this_x = -wh + (x - 1) * ws
                            this_z = -hh + (y - 1) * hs
                        elif self.pixels[x - 1, y + 1] > 127:
                            this_x = -wh + (x - 1) * ws
                            this_z = -hh + (y + 1) * hs
                        elif self.pixels[x + 1, y - 1] > 127:
                            this_x = -wh + (x + 1) * ws
                            this_z = -hh + (y - 1) * hs
                        elif self.pixels[x + 1, y + 1] > 127:
                            this_x = -wh + (x + 1) * ws
                            this_z = -hh + (y + 1) * hs
                verts.append((this_x, hgt, this_z))
                tex_coords.append(((ix - x) * tx, (iy - y) * ty))

        s = 0
        #create one long triangle_strip by alternating X directions
        for y in range(0, iy - 1):
            for x in range(0, ix - 1):
                i = (y * ix) + x
                idx.append((i, i + ix, i + ix + 1))
                idx.append((i + ix + 1, i + 1, i))
                s += 2

        self.buf = []
        self.buf.append(Buffer(self, verts, tex_coords, idx, None, smooth))
Ejemplo n.º 27
0
  def groupDrill(gp, np):
    structVList = {}
    offsetVList = {}
    structPList = []
    offset = 0
    #numv = 0
    #numi = 0
    for x in gp:
      if len(x) == 0: continue
      if ("<Group>" in x[0]):
        if len(x[1]) > 0:
          nextnp = np+x[1]
        else:
          nextnp = np+str(randint(10000, 99999))
        groupDrill(x[3], nextnp)
      else:
        #build vertex, polygon, normal, triangles, UVs etc etc
        if "<VertexPool>" in x[0]:
          vp = x[1]
          structVList[vp] = []
          offsetVList[vp] = offset
          for v in x[3]:
            #if "<Vertex>" in v[0]: #try with this test first!
            coords = [float(n) for n in v[2].strip().split()] # before first < error if no coords!
            # texture mapping
            UVcoords = []
            normal = []
            for u in v[3]:
              if "<UV>" in u[0]: UVcoords = [float(n) for n in u[2].strip().split()]
              #TODO get UVtangent and UVbinormal out of UVset (and use them!)
              # if ("<Tangent>" in vList[v]): UVtangent = [float(n) for n in (extBracket("<Tangent>", vList[v]))[0].split()] # not sure how to use this at this stage
              #else: UVtangent = []
              # if ("<Binormal>" in vList[v]): UVbinormal = [float(n) for n in (extBracket("<Binormal>", vList[v]))[0].split()] # not sure how to use this at this stage
              #else: UVbinormal = []
              # normals, used in 'smoothing' edges between polygons
              if "<Normal>" in u[0]: normal = [float(n) for n in u[2].strip().split()]
            vInt = int(v[1])
            while (len(structVList[vp]) < (vInt+1)): structVList[vp].append("")
            structVList[vp][vInt] = (vertex(coords, UVcoords, normal))
            offset += 1
    #
      # now go through splitting out the Polygons from this Group same level as vertexGroup
      if "<Polygon>" in x[0]:
        normal = []
        rgba = []
        MRef = ""
        TRef = ""
        for p in x[3]:
          if ("<Normal>" in p[0]): normal = [float(n) for n in p[2].strip().split()]
          if ("<RGBA>" in p[0]): rgba = [float(n) for n in p[2].strip().split()]
          if ("<MRef>" in p[0]): MRef = p[2].strip()
          if ("<TRef>" in p[0]): TRef = p[2].strip()
          if ("<VertexRef>" in p[0]):
            vref = []
            for n in p[2].strip().split():
              vref.append(int(n))
              #numv += 1
              #numi += 3
            #numi -= 6 # number of corners of triangle = (n-2)*3 where n is the number of corners of face
            vpKey = p[3][0][2].strip() # ought to do a for r in p[3]; if "Ref in...
        # add to list
        #while (len(structPList) < (p+1)): structPList.append("")
        #
        structPList.append(polygon(normal, rgba, MRef, TRef, vref, vpKey))

    # now go through the polygons in order of vertexPool+id, trying to ensure that the polygon arrays in each group are built in the order of vertexPool names
    # only cope with one material and one texture per group
    #numv -= 1
    #numi -= 1
    g_vertices = []
    g_normals = []
    g_tex_coords = []
    g_indices = []
    nv = 0 # vertex counter in this material
    #ni = 0 # triangle vertex count in this material

    gMRef = ""
    gTRef = ""
    nP = len(structPList)
    for p in xrange(nP):
      if (len(structPList[p].MRef) > 0): gMRef = structPList[p].MRef
      else: gMRef = ""
      if (len(structPList[p].TRef) > 0): gTRef = structPList[p].TRef
      else: gTRef = ""

      vpKey = structPList[p].vpKey
      vref = structPList[p].vref
      startV = nv
      for j in vref:

        if (len(structVList[vpKey][j].normal) > 0): model.vNormal = True
        else: model.vNormal = False
        if model.coordinateSystem == "z-up":
          thisV = [structVList[vpKey][j].coords[1], structVList[vpKey][j].coords[2], -structVList[vpKey][j].coords[0]]
          if model.vNormal:
            thisN = [structVList[vpKey][j].normal[1], structVList[vpKey][j].normal[2], -structVList[vpKey][j].normal[0]]
        else:
          thisV = [structVList[vpKey][j].coords[0], structVList[vpKey][j].coords[1], -structVList[vpKey][j].coords[2]]
          if model.vNormal:
            thisN = [structVList[vpKey][j].normal[0], structVList[vpKey][j].normal[1], -structVList[vpKey][j].normal[2]]
        g_vertices.append(thisV)
        if model.vNormal: nml = thisN
        else: nml = structPList[p].normal
        g_normals.append(nml)
        uvc = structVList[vpKey][j].UVcoords
        if (len(uvc) == 2):
          g_tex_coords.append(uvc)
        else:
          g_tex_coords.append([0.0, 0.0])
        nv += 1
      n = nv - startV - 1
      for j in range(1, n):
        g_indices.append((startV, startV + j + 1, startV + j))

    ilen = len(g_vertices)
    if ilen > 0:
      model.buf.append(Buffer(model, g_vertices, g_tex_coords, g_indices, g_normals))
      n = len(model.buf) - 1
      model.vGroup[np] = n

      model.buf[n].indicesLen = ilen
      model.buf[n].material = (0.0, 0.0, 0.0, 0.0)
      model.buf[n].ttype = GL_TRIANGLES

      # load the texture file TODO check if same as previously loaded files (for other loadModel()s)
      if (gTRef in model.textureList):
        model.buf[model.vGroup[np]].textures = [model.textureList[gTRef]["texID"]]
        model.buf[model.vGroup[np]].texFile = model.textureList[gTRef]["filename"]
      else:
        model.buf[model.vGroup[np]].textures = []
        model.buf[model.vGroup[np]].texFile = None
        #TODO  don't create this array if texture being used but should be able to combine
        if (gMRef in model.materialList):
          redVal = float(model.materialList[gMRef]["diffr"])
          grnVal = float(model.materialList[gMRef]["diffg"])
          bluVal = float(model.materialList[gMRef]["diffb"])
          model.buf[model.vGroup[np]].material = (redVal, grnVal, bluVal, 1.0)
          model.buf[model.vGroup[np]].unib[3:6] = [redVal, grnVal, bluVal]

        else: model.buf[model.vGroup[np]].material = (0.0, 0.0, 0.0, 0.0)
Ejemplo n.º 28
0
    def __init__(self,
                 camera=None,
                 light=None,
                 w=1.0,
                 h=1.0,
                 d=1.0,
                 name="",
                 x=0.0,
                 y=0.0,
                 z=0.0,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0,
                 tw=1.0,
                 th=1.0,
                 td=1.0):
        """uses standard constructor for Shape extra Keyword arguments:

      *w*
        width
      *h*
        height
      *d*
        depth
      *tw*
        scale width
      *th*
        scale height
      *td*
        scale depth

    The scale factors are the multiple of the texture to show along that
    dimension. For no distortion of the image the scale factors need to be
    proportional to the relative dimension.
    """
        super(Cuboid, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                     1.0, 1.0, 1.0, cx, cy, cz)

        if VERBOSE:
            print("Creating cuboid ...")

        self.width = w
        self.height = h
        self.depth = d
        self.ssize = 36
        self.ttype = GL_TRIANGLES

        ww = w / 2.0
        hh = h / 2.0
        dd = d / 2.0

        #cuboid data - faces are separated out for texturing..

        self.vertices = ((-ww, hh, dd), (ww, hh, dd), (ww, -hh, dd),
                         (-ww, -hh, dd), (ww, hh, dd), (ww, hh, -dd),
                         (ww, -hh, -dd), (ww, -hh, dd), (-ww, hh, dd),
                         (-ww, hh, -dd), (ww, hh, -dd), (ww, hh, dd),
                         (ww, -hh, dd), (ww, -hh, -dd), (-ww, -hh, -dd),
                         (-ww, -hh, dd), (-ww, -hh, dd), (-ww, -hh, -dd),
                         (-ww, hh, -dd), (-ww, hh, dd), (-ww, hh, -dd),
                         (ww, hh, -dd), (ww, -hh, -dd), (-ww, -hh, -dd))
        self.normals = ((0.0, 0.0, 1), (0.0, 0.0, 1), (0.0, 0.0, 1), (0.0, 0.0,
                                                                      1),
                        (1, 0.0, 0), (1, 0.0, 0), (1, 0.0, 0), (1, 0.0, 0),
                        (0.0, 1, 0), (0.0, 1, 0), (0.0, 1, 0), (0.0, 1, 0),
                        (0.0, -1, 0), (0, -1, 0), (0.0, -1, 0), (0.0, -1, 0),
                        (-1, 0.0, 0), (-1, 0.0, 0), (-1, 0.0, 0), (-1, 0.0, 0),
                        (0.0, 0.0, -1), (0.0, 0.0, -1), (0.0, 0.0,
                                                         -1), (0.0, 0.0, -1))

        self.indices = ((1, 0, 3), (1, 3, 2), (5, 4, 7), (5, 7, 6), (9, 8, 11),
                        (9, 11, 10), (13, 12, 15), (13, 15, 14), (19, 18, 17),
                        (19, 17, 16), (20, 21, 22), (20, 22, 23))

        #texture scales (each set to 1 would stretch it over face)
        tw = tw / 2.0
        th = th / 2.0
        td = td / 2.0

        self.tex_coords = (
            (0.5 + tw, 0.5 - th),
            (0.5 - tw, 0.5 - th),
            (0.5 - tw, 0.5 + th),
            (0.5 + tw, 0.5 + th),  #tw x th
            (0.5 + td, 0.5 - th),
            (0.5 - td, 0.5 - th),
            (0.5 - td, 0.5 + th),
            (0.5 + td, 0.5 + th),  # td x th
            (0.5 - tw, 0.5 - th),
            (0.5 + tw, 0.5 - th),
            (0.5 + tw, 0.5 + th),
            (0.5 - tw, 0.5 + th),  # tw x th
            (0.5 + tw, 0.5 + td),
            (0.5 - tw, 0.5 + td),
            (0.5 - tw, 0.5 - td),
            (0.5 + tw, 0.5 - td),  # tw x td
            (0.5 - td, 0.5 + th),
            (0.5 + td, 0.5 + th),
            (0.5 + td, 0.5 - th),
            (0.5 - td, 0.5 - th),  # td x th
            (0.5 - tw, 0.5 - th),
            (0.5 + tw, 0.5 - th),
            (0.5 + tw, 0.5 + th),
            (0.5 - tw, 0.5 + th))  # tw x th

        self.buf = []
        self.buf.append(
            Buffer(self, self.vertices, self.tex_coords, self.indices,
                   self.normals))
Ejemplo n.º 29
0
    def __init__(self,
                 camera=None,
                 light=None,
                 font=None,
                 string=None,
                 x=0.0,
                 y=0.0,
                 z=1.0,
                 sx=DEFAULT_FONT_SCALE,
                 sy=DEFAULT_FONT_SCALE,
                 is_3d=True,
                 size=DEFAULT_FONT_SIZE,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 justify="C"):
        """Standard Shape constructor without the facility to change z scale or
    any of the offset values. Additional keyword arguments:

      *font*
        Pngfont or Font class object.
      *string*
        of ASCI characters in range(32, 128) plus 10 = \n Line Feed
      *sx, sy*
        These change the actual vertex positions of the shape rather than being
        used as scaling factors. This is to avoid distortion when the string is
        drawn using an orthographic camera
      *is_3d*
        alters the values of sx and sy to give reasonable sizes with 2D or 3D
        drawing
      *size*
        approximate size of the characters in inches - obviously for 3D drawing
        of strings this will depend on camera fov, display size and how far away
        the string is placed
      *justify*
        default C for central, can be R for right or L for left
    """
        if not is_3d:
            sy = sx = size * 4.0
        super(String, self).__init__(camera, light, "", x, y, z, rx, ry, rz,
                                     1.0, 1.0, 1.0, 0.0, 0.0, 0.0)

        if VERBOSE:
            print("Creating string ...")

        self.verts = []
        self.texcoords = []
        self.norms = []
        self.inds = []
        temp_verts = []

        xoff = 0.0
        yoff = 0.0
        lines = 0
        if not isinstance(string, text_type):
            string = string.decode('utf-8')
        nlines = string.count("\n") + 1

        def make_verts():  #local function to justify each line
            if justify.upper() == "C":
                cx = xoff / 2.0
            elif justify.upper() == "L":
                cx = 0.0
            else:
                cx = xoff
            for j in temp_verts:
                self.verts.append([
                    (j[0] - cx) * sx,
                    (j[1] + nlines * font.height * GAP / 2.0 - yoff) * sy, j[2]
                ])

        default = font.glyph_table.get(unichr(0), None)
        for i, c in enumerate(string):
            if c == '\n':
                make_verts()
                yoff += font.height * GAP
                xoff = 0.0
                temp_verts = []
                lines += 1
                continue  #don't attempt to draw this character!

            glyph = font.glyph_table.get(c, default)
            if not glyph:
                continue
            w, h, texc, verts = glyph[0:4]
            for j in verts:
                temp_verts.append((j[0] + xoff, j[1], j[2]))
            xoff += w
            for j in texc:
                self.texcoords.append(j)
            self.norms.extend(_NORMALS)

            # Take Into account unprinted \n characters
            stv = 4 * (i - lines)
            self.inds.extend([[stv, stv + 2, stv + 1], [stv, stv + 3,
                                                        stv + 2]])

        make_verts()

        self.buf = []
        self.buf.append(
            Buffer(self, self.verts, self.texcoords, self.inds, self.norms))
        self.buf[0].textures = [font]
        self.buf[0].unib[1] = -1.0

        self.string = string  #for later use in quick_change() method
        self.maxlen = len(string)
        self.font = font
Ejemplo n.º 30
0
  def __init__(self, mapfile, camera=None, light=None,
               width=100.0, depth=100.0, height=10.0,
               divx=0, divy=0, ntiles=1.0, name="",
               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, cx=0.0, cy=0.0, cz=0.0, smooth=True, 
               cubic=False, texmap=None):
    """uses standard constructor for Shape

    Arguments:
      *mapfile*
        Greyscale image path/file, string. If multiple bytes per pixel
        only the first one will be used for elevation. jpg files will
        create slight errors that will cause mis-matching of edges for
        tiled maps (i.e. use png for these) NB also see divx, divy below
        i.e. div=64x64 requires image 65x65 pixels

    Keyword arguments:
      *width, depth, height*
        Of the map in world units.
      *divx, divy*
        Number of divisions into which the map will be divided.
        to create vertices (vertices += 1) NB if you want to create a map
        with 64x64 divisions there will be 65x65 vertices in each direction so
        the mapfile (above) needs to 65x65 pixels in order to specify
        elevations precisely and avoid resizing errors.
      *ntiles*
        Number of repeats for tiling the texture image.
      *smooth*
        Calculate normals with averaging rather than pointing
        straight up, slightly faster if false.
      *texmap*
        Image file path or PIL.Image to be used to represent each of four
        textures and normals using the uv_elev_map shader. The image is
        converted to greyscale and apportioned between darkest (first and
        second entries in Buffer.textures list) and lightest (seventh and
        eighth entries). The resulting 0.0, 1.0, 2.0 or 3.0 is added to the
        uv texture coordinate i.e. Buffer.array_buffer[:,6:8]
    """
    super(ElevationMap, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
                                       sx, sy, sz, cx, cy, cz)
    divx += 1 # one more vertex in each direction than number of divisions
    divy += 1
    if divx > 200 or divy > 200:
      LOGGER.warning("... Map size can't be bigger than 199x199 divisions")
      divx = 200
      divy = 200
    #print(type(mapfile), type(""))

    if PIL_OK:
      try:
        if '' + mapfile == mapfile: #HORRIBLE. Only way to cope with python2v3
          mapfile = file_pathify(mapfile)
          LOGGER.debug("Loading height map ...%s", mapfile)

          im = Image.open(mapfile)
        else:
          im = mapfile #allow image files to be passed as mapfile
      except:
        im = mapfile
      ix, iy = im.size
      if (ix > 200 and divx == 0) or (ix != divx and iy != divy):
        if divx == 0:
          divx = 200
          divy = 200
        im = im.resize((divx, divy), Image.ANTIALIAS)
        ix, iy = im.size
      im = im.convert('L')
      im = im.transpose(Image.FLIP_TOP_BOTTOM)
      im = im.transpose(Image.FLIP_LEFT_RIGHT)
      self.pixels = im.load()
      if texmap is not None:
        try:
          texmap = file_pathify(texmap)
          tm = Image.open(texmap)
        except:
          tm = texmap
        tm = tm.convert('L')
        tm = tm.resize((ix, iy))
        tm = np.array(tm)
        tm = np.floor(tm * 3.99 / (tm.max() - tm.min())) # set to 0.0, 1.0, 2.0, 3.0
        tm = tm[::-1,::-1].T # effectively reflect and rotate to match mapping of elevation

    else: 
      ''' images saved as compressed numpy npz file. No resizing so needs 
      to be right size.'''
      mapfile = file_pathify(mapfile)
      self.pixels = np.load(mapfile)['arr_0'][::-1,::-1] # has to be saved with default key
      ix, iy = self.pixels.shape[:2]
    
    self.width = width
    self.depth = depth
    self.height = height
    self.ix = ix
    self.iy = iy
    self.ht_y = 0.0
    self.ht_n = np.array([0.0, 1.0, 0.0])

    LOGGER.debug("Creating Elevation Map ...%d x %d", ix, iy)

    self.wh = width * 0.5
    self.hh = depth * 0.5
    self.ws = width / (ix - 1.0)
    self.hs = depth / (iy - 1.0)
    self.ht = height / 255.0
    tx = 1.0 * ntiles / ix
    ty = 1.0 * ntiles / iy

    verts = []
    tex_coords = []
    idx = []

    for y in range(iy):
      for x in range(ix):
        hgt = self.pixels[x, y] * self.ht
        verts.append((-self.wh + x * self.ws, 
                      hgt, 
                      -self.hh + y * self.hs))
        if texmap is not None:
          tex_n = tm[x, y]
        else:
          tex_n = 0.0
        tex_coords.append((tex_n + (ix - x) * tx, (iy - y) * ty))

    s = 0
    #create one long triangle_strip by alternating X directions
    for y in range(0, iy-1):
      for x in range(0, ix-1):
        i = (y * ix)+x
        idx.append((i, i+ix, i+ix+1))
        idx.append((i+ix+1, i+1, i))
        s += 2

    self.buf = [Buffer(self, verts, tex_coords, idx, None, smooth)]
Ejemplo n.º 31
0
    def __init__(self,
                 mapfile,
                 camera=None,
                 light=None,
                 width=100.0,
                 depth=100.0,
                 height=10.0,
                 divx=0,
                 divy=0,
                 ntiles=1.0,
                 name="",
                 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,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0,
                 smooth=True,
                 cubic=False):
        """uses standard constructor for Shape
    
    Arguments:
      *mapfile*
        Greyscale image path/file, string.
    
    Keyword arguments:
      *width, depth, height*
        Of the map in world units.
      *divx, divy*
        Number of divisions into which the map will be divided.
        to create vertices
      *ntiles*
        Number of repeats for tiling the texture image.
      *smooth*
        Calculate normals with averaging rather than pointing
        straight up, slightly faster if false.
    """
        super(ElevationMap, self).__init__(camera, light, name, x, y, z, rx,
                                           ry, rz, sx, sy, sz, cx, cy, cz)
        if VERBOSE:
            print "Loading height map ...", mapfile

        if divx > 200 or divy > 200:
            print "... Map size can't be bigger than 200x200 divisions"
            divx = 200
            divy = 200

        im = Image.open(mapfile)
        im = PIL.ImageOps.invert(im)
        ix, iy = im.size
        if (ix > 200 and divx == 0) or (divx > 0):
            if divx == 0:
                divx = 200
                divy = 200
            im = im.resize((divx, divy), Image.ANTIALIAS)
            ix, iy = im.size
        if not im.mode == "P":
            im = im.convert('P', palette=Image.ADAPTIVE)

        im = im.transpose(Image.FLIP_TOP_BOTTOM)
        im = im.transpose(Image.FLIP_LEFT_RIGHT)
        self.pixels = im.load()
        self.width = width
        self.depth = depth
        self.height = height
        self.ix = ix
        self.iy = iy
        self.ttype = GL_TRIANGLE_STRIP

        if VERBOSE:
            print "Creating Elevation Map ...", ix, iy

        wh = width * 0.5
        hh = depth * 0.5
        ws = width / ix
        hs = depth / iy
        ht = height / 255.0
        tx = 1.0 * ntiles / ix
        ty = 1.0 * ntiles / iy

        verts = []
        norms = []
        tex_coords = []
        idx = []

        for y in xrange(0, iy):
            for x in xrange(0, ix):
                hgt = (self.pixels[x, y]) * ht
                this_x = -wh + x * ws
                this_z = -hh + y * hs
                if cubic:
                    """ this is a bit experimental. It tries to make the map either zero
          or height high. Vertices are moved 'under' adjacent ones if there is
          a step to make vertical walls. Goes wrong in places - mainly because
          it doesn't check diagonals
          """
                    if hgt > height / 2:
                        hgt = height
                    else:
                        hgt = 0.0
                    if hgt == 0 and y > 0 and y < iy - 1 and x > 0 and x < ix - 1:
                        if self.pixels[x - 1, y] > 127:
                            this_x = -wh + (x - 1) * ws
                        elif self.pixels[x + 1, y] > 127:
                            this_x = -wh + (x + 1) * ws
                        elif self.pixels[x, y - 1] > 127:
                            this_z = -hh + (y - 1) * hs
                        elif self.pixels[x, y + 1] > 127:
                            this_z = -hh + (y + 1) * hs
                        elif self.pixels[x - 1, y - 1] > 127:
                            this_x = -wh + (x - 1) * ws
                            this_z = -hh + (y - 1) * hs
                        elif self.pixels[x - 1, y + 1] > 127:
                            this_x = -wh + (x - 1) * ws
                            this_z = -hh + (y + 1) * hs
                        elif self.pixels[x + 1, y - 1] > 127:
                            this_x = -wh + (x + 1) * ws
                            this_z = -hh + (y - 1) * hs
                        elif self.pixels[x + 1, y + 1] > 127:
                            this_x = -wh + (x + 1) * ws
                            this_z = -hh + (y + 1) * hs
                verts.append((this_x, hgt, this_z))
                tex_coords.append(((ix - x) * tx, (iy - y) * ty))

        s = 0
        #create one long triangle_strip by alternating X directions
        for y in range(0, iy - 1):
            for x in range(0, ix - 1):
                i = (y * ix) + x
                idx.append((i, i + ix, i + ix + 1))
                idx.append((i + ix + 1, i + 1, i))
                s += 2

        self.buf = []
        self.buf.append(Buffer(self, verts, tex_coords, idx, None, smooth))
Ejemplo n.º 32
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)