def __init__(self, name): self.aabb = aabb((-16, -16, 0), (16, 16, 72)) self.swept_aabb = aabb((0, 0, 0), (0, 0, 0)) self.camera = camera.firstperson() self.position = vector.vec3(0, 0, 0) self.old_position = vector.vec3(0, 0, 0) self.rotation = vector.vec3(0, 0, 0) self.front = vector.vec3(0, 1, 0) self.speed = 256 self.name = name self.onGround = False self.velocity = vector.vec3()
def __init__(self, name): self.aabb = aabb((-.5, -.5, 0), (.5, .5, 2)) self.swept_aabb = aabb((0, 0, 0), (0, 0, 0)) #can be local to update? self.camera = camera.firstperson() self.position = vector.vec3(0, 0, 0) self.old_position = vector.vec3(0, 0, 0) self.rotation = vector.vec3(0, 0, 0) self.front = vector.vec3(0, 1, 0) self.speed = 10 self.name = name self.onGround = False self.velocity = vector.vec3()
def update(self, mouse, keys, dt): global gravity self.camera.update(mouse) self.rotation = self.camera.rotation wish_vector = vector.vec3() wish_vector.x = ((SDLK_d in keys) - (SDLK_a in keys)) wish_vector.y = ((SDLK_w in keys) - (SDLK_s in keys)) true_wish = wish_vector.rotate(0, 0, -self.rotation.z) self.front = vector.vec3(0, 1, 0).rotate(0, 0, -self.rotation.z) self.velocity += true_wish * self.speed * dt self.velocity += 0.5 * gravity * dt self.onGround = False self.old_position = self.position self.position += self.velocity min_x = min(self.old_position.x, self.position.x) max_x = max(self.old_position.x, self.position.x) min_y = min(self.old_position.y, self.position.y) max_y = max(self.old_position.y, self.position.y) min_z = min(self.old_position.z, self.position.z) max_z = max(self.old_position.z, self.position.z) self.swept_aabb = aabb( vector.vec3(min_x, min_y, min_z) + self.aabb.min, vector.vec3(max_x, max_y, max_z) + self.aabb.max) corners = [] for i in range(8): x = min_x if i // 4 % 2 == 0 else max_x y = min_y if i // 2 % 2 == 0 else max_y z = min_z if i % 2 == 0 else max_z corners.append(vector.vec3(x, y, z)) global planes for plane, faces in planes.items(): if any(self.swept_aabb.intersects(x) for x in faces): intersect_depth = 0 plane_dot = vector.dot(self.position, plane[0]) ### Some planes have negative D (distance) ### since some planes can face towards O (origin point) ### so it will be > for positive D and < for negative if plane[1] > 0: if plane_dot > plane[1]: intersect_depth = plane_dot + plane[1] else: if plane_dot < plane[1]: intersect_depth = plane_dot - plane[1] self.position += vector.vec3(*plane[0]) * intersect_depth if intersect_depth != 0: global physFrozen physFrozen = True plane_v = vector.vec3(*plane[0]) print( f'({plane_v:.2f}) {plane[1]:.2f}D = {plane_dot:.2f} ({intersect_depth:.2f})' ) self.onGround = True if SDLK_SPACE in keys: #JUMP self.velocity.z += 20
def update(self, mouse, keys, dt): #GRAVITY VELOCITY / ACCELERATION self.camera.update(mouse) self.rotation = self.camera.rotation wish_vector = vector.vec3() wish_vector.x = ((SDLK_d in keys) - (SDLK_a in keys)) wish_vector.y = ((SDLK_w in keys) - (SDLK_s in keys)) true_wish = wish_vector.rotate(0, 0, -self.rotation.z) self.front = vector.vec3(0, 1, 0).rotate(0, 0, -self.rotation.z) #GET CURRENT FRICTION (FROM SURFACE CONTACT) true_speed = self.speed * (1 if self.onGround else 1.75) self.position += true_wish * true_speed * dt #NEED FRICTION if not self.onGround: self.velocity += 0.5 * vector.vec3(0, 0, -9.81) * dt #GRAVITY self.onGround = False self.old_position = self.position self.position += self.velocity #min maxing old & new positions min_x = min(self.old_position.x, self.position.x) max_x = max(self.old_position.x, self.position.x) min_y = min(self.old_position.y, self.position.y) max_y = max(self.old_position.y, self.position.y) min_z = min(self.old_position.z, self.position.z) max_z = max(self.old_position.z, self.position.z) self.swept_aabb = aabb( vector.vec3(min_x, min_y, min_z) + self.aabb.min, vector.vec3(max_x, max_y, max_z) + self.aabb.max) global planes for plane in planes: #filtered with position & bsp nodes #also should combine results rather than applying in order if self.swept_aabb.intersects(plane.aabb): p = vector.dot(self.position, plane.normal) max_p = self.swept_aabb.depth_along_axis(plane.normal) if p <= max_p and p <= abs(plane.distance): #simplify self.position += math.fsum([plane.distance, -p ]) * plane.normal self.onGround = True self.velocity = vector.vec3() #friction, surf & bounce ## self.velocity -= self.velocity * plane.normal if SDLK_SPACE in keys: #JUMP self.velocity.z += .6
def main(width, height): SDL_Init(SDL_INIT_VIDEO) window = SDL_CreateWindow(b'SDL2 OpenGL', SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS) glContext = SDL_GL_CreateContext(window) SDL_GL_SetSwapInterval(0) glClearColor(0.1, 0.1, 0.1, 0.0) gluPerspective(90, width / height, 0.1, 4096) glRotate(90, -1, 0, 0) glTranslate(0, 8, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glEnable(GL_DEPTH_TEST) glPointSize(8) mouse = vector.vec2(0, 0) spec_mouse = mouse keys = [] bsp = bsp_tool.bsp("../mapsrc/bsp_import_props.bsp") filtered_faces = list(filter(lambda x: x['lightofs'] != -1, bsp.FACES)) global planes planes = {} # planes = {plane: [*faces], ...} for face in filtered_faces: plane = bsp.PLANES[face['planenum']] verts = bsp.verts_of(face) face_bounds = aabb(*verts_to_box(verts)) plane_key = (plane['normal'], plane['dist']) if plane_key in planes.keys(): planes[plane_key].append(face_bounds) else: planes[plane_key] = [face_bounds] bsptris = list( itertools.chain(*[bsp.verts_of(face) for face in filtered_faces])) client0 = client('b!scuit') #TODO: draw client name at client position spectator_camera = camera.freecam((0, 0, 128), (0, 0, 0), speed=368) active_camera = 0 SDL_SetRelativeMouseMode(SDL_TRUE) SDL_SetWindowGrab(window, SDL_TRUE) SDL_CaptureMouse(SDL_TRUE) global physFrozen physFrozen = False global tickrate tickrate = 1 / 0.015 #66.67 for tf2 (~15ms per frame) tick_number = 0 dt = 1 / tickrate oldtime = time() event = SDL_Event() while True: while SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == SDL_QUIT or event.key.keysym.sym == SDLK_ESCAPE and event.type == SDL_KEYDOWN: SDL_GL_DeleteContext(glContext) SDL_DestroyWindow(window) SDL_Quit() return False if event.type == SDL_KEYDOWN: keys.append(event.key.keysym.sym) if event.type == SDL_KEYUP: while event.key.keysym.sym in keys: keys.remove(event.key.keysym.sym) if event.type == SDL_MOUSEMOTION: mouse = vector.vec2(event.motion.xrel, event.motion.yrel) SDL_WarpMouseInWindow(window, width // 2, height // 2) if event.type == SDL_MOUSEBUTTONDOWN: if event.button.button == SDL_BUTTON_RIGHT: active_camera = 0 if active_camera == 1 else 1 if SDLK_r in keys: client0.spawn((0, 0, 2048)) if SDLK_BACKQUOTE in keys: physFrozen = False if SDLK_SPACE in keys: physFrozen = True dt = time() - oldtime if dt >= 1 / tickrate: if not physFrozen: print('TICK #{}'.format(tick_number)) tick_number += 1 client0.report() if active_camera == 0: if not physFrozen: client0.update(mouse, keys, 1 / tickrate) else: spec_mouse += mouse spectator_camera.update(spec_mouse, keys, 1 / tickrate) if not physFrozen: client0.update( vector.vec2(0, 0), [], 1 / tickrate) #inputless update to maintain physics mouse = vector.vec2(0, 0) dt -= 1 / tickrate oldtime = time() #DISPLAY glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() gluPerspective(90, width / height, 0.1, 4096) if active_camera == 0: if not physFrozen: client0.set_view_lerp(dt) else: client0.set_view() else: spectator_camera.set() glPolygonMode(GL_BACK, GL_FILL) for face in filtered_faces: normal = bsp.PLANES[face['planenum']]['normal'] normal = [(x + 1) / 2 for x in normal] colour = normal[0] / 3 + 1 / 3 * normal[1] / 3 + 2 / 3 * normal[ 2] / 3 glColor(*[[colour] * 3]) glBegin(GL_POLYGON) for vertex in bsp.verts_of(face): glVertex(*vertex) glEnd() glPolygonMode(GL_BACK, GL_LINE) # normal indicator ## glBegin(GL_LINES) ## for plane in planes: ## center = sum(plane.aabb, vector.vec3()) / 2 ## glColor(0, 1, 0) ## glVertex(*center) ## glColor(.1, .1, .1) ## glVertex(*(center + plane.normal * 64)) ## glEnd() if not physFrozen: client0.draw_lerp(dt) else: client0.draw() SDL_GL_SwapWindow(window)
def __init__(self, normal, distance, BBmin, BBmax): self.normal = vector.vec3(normal).normalise() self.distance = distance self.aabb = aabb(BBmin, BBmax)