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')
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
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)