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))
def draw(self, texID=None, n=None): # TODO: shadows Shape.draw. if self.exf != 'egg' and self.exf != 'obj': return # From loaderEgg.draw, probably added by paddy gaunt 15 June 2012 texToUse = None if texID != None: texToUse = texID elif n != None: n = n % (len(self.textureList)) i = 0 for t in self.textureList: if i == n: texToUse = self.textureList[t].texID break i += 1 mtrx = Matrix() mtrx.push() self.transform() for g in self.vGroup: opengles.glShadeModel(GL_SMOOTH) opengles.glVertexPointer( 3, GL_FLOAT, 0, self.vGroup[g].vertices); opengles.glNormalPointer( GL_FLOAT, 0, self.vGroup[g].normals); texture = texToUse or self.vGroup[g].texID with Texture.Loader(texture, self.vGroup[g].tex_coords): #TODO enable material colours as well as textures from images material = self.vGroup[g].material if material: #opengles.glMaterialfv(GL_FRONT, GL_DIFFUSE, material); opengles.glEnableClientState(GL_COLOR_ARRAY) opengles.glColorPointer(4, GL_UNSIGNED_BYTE, 0, material); opengles.glDrawElements(GL_TRIANGLES, self.vGroup[g].indicesLen, GL_UNSIGNED_SHORT, self.vGroup[g].indices) opengles.glShadeModel(GL_FLAT) mtrx.pop() for c in self.childModel: relx, rely, relz = c.x, c.y, c.z relrotx, relroty, relrotz = c.rotx, c.roty, c.rotz rval = rotate_vec(self.rotx, self.roty, self.rotz, (c.x, c.y, c.z)) c.x, c.y, c.z = self.x + rval[0], self.y + rval[1], self.z + rval[2] c.rotx, c.roty, c.rotz = (self.rotx + c.rotx, self.roty + c.roty, self.rotz + c.rotz) c.draw() #should texture override be passed down to children? c.x, c.y, c.z = relx, rely, relz c.rotx, c.roty, c.rotz = relrotx, relroty, relrotz
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)
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 buf = self.buf[0].array_buffer # alias to tidy code vertices = buf[:,0:3] if len(buf) > 0 else buf normals = buf[:,3:6] if len(buf) > 0 else buf tex_coords = buf[:,6:8] if len(buf) > 0 else buf #TODO this will only cope with N_BYTES == 32 indices = self.buf[0].element_array_buffer[:] for b in buflist: if not(type(b[0]) is Buffer): bufr = b[0].buf[0] else: bufr = b[0] n = len(bufr.array_buffer) if VERBOSE: print("Merging", bufr.name) original_vertex_count = len(vertices) 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 = np.append(vertices, vrot) normals = np.append(normals, nrot) if bufr.array_buffer.shape[1] == 8: tex_coords = np.append(tex_coords, bufr.array_buffer[:,6:8]) else: tex_coords = np.append(tex_coords, np.zeros((n, 2))) n = int(len(vertices) / 3) vertices.shape = (n, 3) normals.shape = (n, 3) tex_coords.shape = (n, 2) #ctypes.restype = ctypes.c_short # TODO: remove this side-effect. faces = bufr.element_array_buffer + original_vertex_count indices = np.append(indices, faces) n = int(len(indices) / 3) indices.shape = (n, 3) self.buf = [Buffer(self, vertices, tex_coords, indices, normals)] # add some Buffer details from last one in list self.buf[0].shader = bufr.shader self.buf[0].material = bufr.material self.buf[0].textures = bufr.textures self.buf[0].draw_method = bufr.draw_method self.buf[0].unib = bufr.unib
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 buf = self.buf[0].array_buffer # alias to tidy code vertices = buf[:,0:3] if len(buf) > 0 else buf normals = buf[:,3:6] if len(buf) > 0 else buf tex_coords = buf[:,6:8] if len(buf) > 0 else buf #TODO this will only cope with N_BYTES == 32 indices = self.buf[0].element_array_buffer[:] for b in buflist: if not(type(b[0]) is Buffer): 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) 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 = np.append(vertices, vrot) normals = np.append(normals, nrot) if bufr.array_buffer.shape[1] == 8: tex_coords = np.append(tex_coords, bufr.array_buffer[:,6:8]) else: tex_coords = np.append(tex_coords, np.zeros((n, 2))) n = int(len(vertices) / 3) vertices.shape = (n, 3) normals.shape = (n, 3) tex_coords.shape = (n, 2) #ctypes.restype = ctypes.c_short # TODO: remove this side-effect. faces = bufr.element_array_buffer + original_vertex_count indices = np.append(indices, faces) n = int(len(indices) / 3) indices.shape = (n, 3) self.buf = [Buffer(self, vertices, tex_coords, indices, normals)] # add some Buffer details from last one in list self.buf[0].shader = bufr.shader self.buf[0].material = bufr.material self.buf[0].textures = bufr.textures self.buf[0].draw_method = bufr.draw_method self.buf[0].unib = bufr.unib
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 buf = self.buf[0].array_buffer # alias to tidy code vertices = buf[:, 0:3] if len(buf) > 0 else buf normals = buf[:, 3:6] if len(buf) > 0 else buf tex_coords = buf[:, 6:8] if len( buf) > 0 else buf #TODO this will only cope with N_BYTES == 32 indices = self.buf[0].element_array_buffer[:] for b in buflist: if not (type(b[0]) is Buffer): bufr = b[0].buf[0] else: bufr = b[0] n = len(bufr.array_buffer) if VERBOSE: print("Merging", bufr.name) original_vertex_count = len(vertices) vrot = [] nrot = [] for v in range(0, n): # Scale, offset and store vertices vx, vy, vz = rotate_vec(b[4], b[5], b[6], bufr.array_buffer[v, 0:3]) vrot.append( (vx * b[7] + b[1], vy * b[8] + b[2], vz * b[9] + b[3])) # Rotate normals nrot.append( rotate_vec(b[4], b[5], b[6], bufr.array_buffer[v, 3:6])) vertices = np.append(vertices, vrot) normals = np.append(normals, nrot) tex_coords = np.append(tex_coords, bufr.array_buffer[:, 6:8]) n = int(len(vertices) / 3) vertices.shape = (n, 3) normals.shape = (n, 3) tex_coords.shape = (n, 2) #ctypes.restype = ctypes.c_short # TODO: remove this side-effect. faces = bufr.element_array_buffer + original_vertex_count indices = np.append(indices, faces) n = int(len(indices) / 3) indices.shape = (n, 3) self.buf = [] self.buf.append(Buffer(self, vertices, tex_coords, indices, normals))