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