def __init__(self, Side=None, Up=None, Forward=None,Position=None): # upward-pointing unit basis vector if Up: self._up = Up else: self._up = vec3() # forward-pointing unit basis vector if Forward: self._forward =Forward else: self._forward = vec3() # origin of local space if Position: self._position = Position else: self._position = vec3() # side-pointing unit basis vector if Side: self._side = Side else: self._side = vec3() self.setUnitSideFromForwardAndUp() if (not Side) & (not Up) & (not Forward) & (not Position): self.resetLocalSpace()
def drawXZLineGrid(size, subsquares, center, color): """ draw a square grid of lines on the XZ (horizontal) plane. ("size" is the length of a side of the overall grid, "subsquares" is the number of subsquares along each edge (for example a standard checkboard has eight), "center" is the 3d position of the center of the grid, lines are drawn in the specified "color".) """ warnIfInUpdatePhase("drawXZLineGrid") half = size / 2 spacing = size / subsquares # set grid drawing color glColor3f(color.x, color.y, color.z) # draw a square XZ grid with the given size and line count glBegin(GL_LINES) q = -1 * half for i in range(subsquares + 1): x1 = vec3(q, 0, half) # along X parallel to Z x2 = vec3(q, 0, -1 * half) z1 = vec3(half, 0, q) # along Z parallel to X z2 = vec3(-1 * half, 0, q) iglVertexVec3(x1 + center) iglVertexVec3(x2 + center) iglVertexVec3(z1 + center) iglVertexVec3(z2 + center) q += spacing glEnd()
def raytrace(r, scene, depth): # Determine the closest hits distances = [s.intersect(r, 0.001, 1.0e39) for s in scene] nearest = ft.reduce(np.minimum, distances) # Ambient color = rgb(0.0, 0.0, 0.0) unit_dir = unit_vector(r.direction()) t = (unit_dir.y + 1.0) * 0.5 # bgc = (vec3(1.0, 1.0, 1.0)*(1.0 - t) + vec3(0.5, 0.7, 1.0)*t) bgc = vec3(0.5, 0.7, 1.0) * t for (s, d) in zip(scene, distances): hit = (nearest != 1.0e39) & (d == nearest) print("depth: %s | Radius: %s | Shape: %s" % (depth, s.radius, hit.shape)) time.sleep(0.1) if np.any(hit) and depth < 5: dc = np.extract(hit, d) oc = r.origin().extract(hit) dirc = r.direction().extract(hit) er = ray(oc, dirc) p = er.point_at_parameter(dc) N = (p - s.center) / vec3(s.radius, s.radius, s.radius) shader = s.material() scattered = shader.scatter(er, p, N) cc = raytrace(scattered, scene, depth + 1) * shader.albedo # cc = vec3(shader.albedo, shader.albedo, shader.albedo) color += cc.place2(hit, bgc) return color
def __init__(self, Side=None, Up=None, Forward=None, Position=None): # upward-pointing unit basis vector if Up: self._up = Up else: self._up = vec3() # forward-pointing unit basis vector if Forward: self._forward = Forward else: self._forward = vec3() # origin of local space if Position: self._position = Position else: self._position = vec3() # side-pointing unit basis vector if Side: self._side = Side else: self._side = vec3() self.setUnitSideFromForwardAndUp() if (not Side) & (not Up) & (not Forward) & (not Position): self.resetLocalSpace()
def drawXZLineGrid(size,subsquares,center,color): """ draw a square grid of lines on the XZ (horizontal) plane. ("size" is the length of a side of the overall grid, "subsquares" is the number of subsquares along each edge (for example a standard checkboard has eight), "center" is the 3d position of the center of the grid, lines are drawn in the specified "color".) """ warnIfInUpdatePhase ("drawXZLineGrid") half = size/2 spacing = size / subsquares # set grid drawing color glColor3f (color.x, color.y, color.z) # draw a square XZ grid with the given size and line count glBegin(GL_LINES) q = -1 * half for i in range(subsquares + 1): x1 = vec3(q, 0, half) # along X parallel to Z x2 = vec3(q, 0, -1*half) z1 = vec3(half, 0, q) # along Z parallel to X z2 = vec3(-1*half, 0, q) iglVertexVec3 (x1 + center) iglVertexVec3 (x2 + center) iglVertexVec3 (z1 + center) iglVertexVec3 (z2 + center) q += spacing glEnd()
class DeferredCircle: radius = 1.0 axis=vec3() center=vec3() color=vec3() segments = 0 filled = True in3d = True
def color(r): hitpts = hit_sphere(vec3(0.0, 0.0, -1.0), 0.4, r) unit_direction = r.direction().norm() t = 0.5 * (unit_direction.y + 1.0) color = (vec3(1.0, 1.0, 1.0) * (1.0 - t) + vec3(0.5, 0.7, 1.0) * t) * hitpts + ( vec3(1.0, 0.0, 0.0) * (1 - hitpts)) return (color)
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 drawAxes(ls,size,color): """ draw the three axes of a LocalSpace: three lines parallel to the basis vectors of the space, centered at its origin, of lengths given by the coordinates of "size". """ x = vec3(size.x / 2, 0, 0) y = vec3(0, size.y / 2, 0) z = vec3(0, 0, size.z / 2) iDrawLine(ls.globalizePosition(x), ls.globalizePosition (x * -1), color) iDrawLine(ls.globalizePosition(y), ls.globalizePosition (y * -1), color) iDrawLine(ls.globalizePosition(z), ls.globalizePosition (z * -1), color)
def drawAxes(ls, size, color): """ draw the three axes of a LocalSpace: three lines parallel to the basis vectors of the space, centered at its origin, of lengths given by the coordinates of "size". """ x = vec3(size.x / 2, 0, 0) y = vec3(0, size.y / 2, 0) z = vec3(0, 0, size.z / 2) iDrawLine(ls.globalizePosition(x), ls.globalizePosition(x * -1), color) iDrawLine(ls.globalizePosition(y), ls.globalizePosition(y * -1), color) iDrawLine(ls.globalizePosition(z), ls.globalizePosition(z * -1), color)
def drawBoxOutline(localSpace, size, color): """ draw the edges of a box with a given position, orientation, size and color. The box edges are aligned with the axes of the given LocalSpace, and it is centered at the origin of that LocalSpace. "size" is the main diagonal of the box. use gGlobalSpace to draw a box aligned with global space """ s = size / 2.0 # half of main diagonal a = vec3(+s.x, +s.y, +s.z) b = vec3(+s.x, -1 * s.y, +s.z) c = vec3(-1.0 * s.x, -1.0 * s.y, +s.z) d = vec3(-1.0 * s.x, +s.y, +s.z) e = vec3(+s.x, +s.y, -1.0 * s.z) f = vec3(+s.x, -1.0 * s.y, -1.0 * s.z) g = vec3(-1.0 * s.x, -1.0 * s.y, -1.0 * s.z) h = vec3(-1.0 * s.x, +s.y, -1.0 * s.z) A = localSpace.globalizePosition(a) B = localSpace.globalizePosition(b) C = localSpace.globalizePosition(c) D = localSpace.globalizePosition(d) E = localSpace.globalizePosition(e) F = localSpace.globalizePosition(f) G = localSpace.globalizePosition(g) H = localSpace.globalizePosition(h)
def random_in_unit_sphere(shape): p = (vec3(np.random.rand(shape), np.random.rand(shape), np.random.rand(shape)) * 2.0) - vec3(1.0, 1.0, 1.0) while True: cond = (p.squared_length() >= 1.0) rp = (vec3(np.random.rand(shape), np.random.rand(shape), np.random.rand(shape)) * 2.0) - vec3(1.0, 1.0, 1.0) np.place(p.x, cond, rp.x) np.place(p.y, cond, rp.y) np.place(p.z, cond, rp.z) if not np.any(cond): break return p
def drawBoxOutline(localSpace,size,color): """ draw the edges of a box with a given position, orientation, size and color. The box edges are aligned with the axes of the given LocalSpace, and it is centered at the origin of that LocalSpace. "size" is the main diagonal of the box. use gGlobalSpace to draw a box aligned with global space """ s = size / 2.0 # half of main diagonal a = vec3(+s.x, +s.y, +s.z) b = vec3(+s.x, -1*s.y, +s.z) c = vec3(-1.0*s.x, -1.0*s.y, +s.z) d = vec3(-1.0*s.x, +s.y, +s.z) e = vec3(+s.x, +s.y, -1.0*s.z) f = vec3(+s.x, -1.0*s.y, -1.0*s.z) g = vec3(-1.0*s.x, -1.0*s.y, -1.0*s.z) h = vec3(-1.0*s.x, +s.y, -1.0*s.z) A = localSpace.globalizePosition (a) B = localSpace.globalizePosition (b) C = localSpace.globalizePosition (c) D = localSpace.globalizePosition (d) E = localSpace.globalizePosition (e) F = localSpace.globalizePosition (f) G = localSpace.globalizePosition (g) H = localSpace.globalizePosition (h)
def raytrace_OLD(r, scene): hitpts = hit_sphere(vec3(0.0, 0.0, -1.0), 0.4, r) m = np.copy(hitpts) unit_direction = unit_vector(r.direction()) t = 0.5 * (unit_direction.y + 1.0) mask = np.where(m > 0.0, 0, 1) N = (r.point_at_parameter(t) - vec3(0.0, 0.0, -1.0)) * (1.0 / 0.4) Nc = (vec3(N.x + 1, N.y + 1, N.z + 1) * 0.5) color = (vec3(1.0, 1.0, 1.0) * (1.0 - t) + vec3(0.5, 0.7, 1.0) * t) * mask + (Nc * (1 - mask)) return (color)
def numpyGradient(): t0 = time.time() nx = 400 ny = 200 # Build array of vectors defined on a normalized plane # aspect ratio r = float(nx) / float(ny) # normalized range S = (0., 1., 1., 0.) # linearly step through each xy pixel and create vector position npx = np.tile(np.linspace(S[0], S[2], nx), ny) npy = np.repeat(np.linspace(S[1], S[3], ny), nx) npz = np.repeat(0.2, (nx * ny)) colorNorm = vec3(npx, npy, npz) fullColor = makeGradient(colorNorm) print("Took %s" % (time.time() - t0)) from PIL import Image rgb = [ Image.fromarray( (255 * np.clip(c, 0, 1).reshape(ny, nx)).astype(np.uint8), "L") for c in colorNorm.components() ] Image.merge("RGB", rgb).save("output_02.png")
def obj_indexed_vertices(filepath): """positions only""" file = open(filepath) v = [] vertex_count = 0 vertices = [] indices = [] for line in file.readlines(): line = line.rstrip("\n") if line.startswith("v"): v.append([float(f) for f in line.split(" ")[1:]]) elif line.startswith("f"): line = line.split(" ")[1:] if len(line) == 4: # QUADS ONLY! for neighbour map for point in line: vertex = v[int(point.split("/")[0]) - 1] vertex = vector.vec3(*vertex) if vertex not in vertices: vertices.append(vertex) indices.append(vertex_count) vertex_count += 1 else: indices.append(vertices.index(vertex)) file.close() return vertices, indices
def __init__(self, center=vec3(0., 0., 0.), radius=0.0, shader=lambertian(0.5)): self.center = center self.radius = radius self.shader = shader
def drawXZCheckerboardGrid (size, subsquares,center,color1,color2): half = float(size)/2 spacing = float(size) / subsquares beginDoubleSidedDrawing() flag1 = false p = -half corner = vec3() for i in range(subsquares): flag2 = flag1 q = -half for j in range(subsquares): corner.set (p, 0, q) corner += center if flag2: col = color1 else: col = color2 iDrawQuadrangle (corner, corner + Vec3 (spacing, 0, 0), corner + Vec3 (spacing, 0, spacing), corner + Vec3 (0, 0, spacing), col ) flag2 = not flag2 q += spacing flag1 = not flag1 p += spacing endDoubleSidedDrawing()
def mouseMotionFunc(x, y): """called when mouse moves and any buttons are down""" global gMouseAdjustingCameraLastX global gMouseAdjustingCameraLastY # are we currently in the process of mouse-adjusting the camera? if (gMouseAdjustingCameraAngle | gMouseAdjustingCameraRadius): # speed factors to map from mouse movement in pixels to 3d motion dSpeed = 0.005 rSpeed = 0.01 # XY distance (in pixels) that mouse moved since last update dx = x - gMouseAdjustingCameraLastX dy = y - gMouseAdjustingCameraLastY gMouseAdjustingCameraLastX = x gMouseAdjustingCameraLastY = y cameraAdjustment = vec3() # set XY values according to mouse motion on screen space if (gMouseAdjustingCameraAngle): cameraAdjustment.x = dx * -1.0 * Speed cameraAdjustment.y = dy * + dSpeed # set Z value according vertical to mouse motion if (gMouseAdjustingCameraRadius): cameraAdjustment.z = dy * rSpeed;
def drawXZCheckerboardGrid(size, subsquares, center, color1, color2): half = float(size) / 2 spacing = float(size) / subsquares beginDoubleSidedDrawing() flag1 = false p = -half corner = vec3() for i in range(subsquares): flag2 = flag1 q = -half for j in range(subsquares): corner.set(p, 0, q) corner += center if flag2: col = color1 else: col = color2 iDrawQuadrangle(corner, corner + Vec3(spacing, 0, 0), corner + Vec3(spacing, 0, spacing), corner + Vec3(0, 0, spacing), col) flag2 = not flag2 q += spacing flag1 = not flag1 p += spacing endDoubleSidedDrawing()
def mouseMotionFunc(x, y): """called when mouse moves and any buttons are down""" global gMouseAdjustingCameraLastX global gMouseAdjustingCameraLastY # are we currently in the process of mouse-adjusting the camera? if (gMouseAdjustingCameraAngle | gMouseAdjustingCameraRadius): # speed factors to map from mouse movement in pixels to 3d motion dSpeed = 0.005 rSpeed = 0.01 # XY distance (in pixels) that mouse moved since last update dx = x - gMouseAdjustingCameraLastX dy = y - gMouseAdjustingCameraLastY gMouseAdjustingCameraLastX = x gMouseAdjustingCameraLastY = y cameraAdjustment = vec3() # set XY values according to mouse motion on screen space if (gMouseAdjustingCameraAngle): cameraAdjustment.x = dx * -1.0 * Speed cameraAdjustment.y = dy * +dSpeed # set Z value according vertical to mouse motion if (gMouseAdjustingCameraRadius): cameraAdjustment.z = dy * rSpeed
def check_materials(vmf, allowed_materials): if not hasattr(vmf.world, "solids") and hasattr(vmf.world, "solid"): # one world brush vmf.world.solids = [vmf.world.solid] del vmf.world.solid all_brushes = copy.deepcopy(vmf.world.solids) for entity in vmf.entities: # brush entities if hasattr(entity, "solid"): if isinstance(entity.solid, vmf_tool.namespace): all_brushes.append(entity.solid) if hasattr(entity, "solids"): if isinstance(entity.solids[0], vmf_tool.namespace): all_brushes += entity.solids for brush in all_brushes: for side in brush.sides: if side.material.upper() not in allowed_materials: face_triangle = [[float(i) for i in xyz.split()] for xyz in side.plane[1:-1].split(") (")] face_center = sum([vector.vec3(*v) for v in face_triangle], vector.vec3()) / 3 yield f"Brush #{brush.id} Face @ {face_center:.2f} uses {side.material}"
def update(self, mousepos, keys, dt): #diagonal? global sensitivity self.rotation.z = mousepos.x * sensitivity self.rotation.x = mousepos.y * sensitivity local_move = vec3() local_move.x = ((SDLK_d in keys) - (SDLK_a in keys)) local_move.y = ((SDLK_w in keys) - (SDLK_s in keys)) local_move.z = ((SDLK_q in keys) - (SDLK_e in keys)) global_move = local_move.rotate(*-self.rotation) self.position += global_move * self.speed * dt
def simpleRaycast(): t0 = time.time() nx = 200 ny = 100 # Build array of vectors defined on a normalized plane # aspect ratio r = float(nx) / float(ny) # normalized range S = (0., 1., 1., 0.) # linearly step through each xy pixel and create vector position npx = np.tile(np.linspace(S[0], S[2], nx), ny) npy = np.repeat(np.linspace(S[1], S[3], ny), nx) npz = np.repeat(0.0, (nx * ny)) origin = vec3(0.0, 0.0, 0.0) # test = ray(origin, lower_left_corner + npx*horizontal + npy*vertical) # print(test) Q = vec3(npx, npy, npz) rdir = Q - origin lower_left_corner = vec3(-2.0, -1.0, -1.0) horizontal = vec3(4.0, 0.0, 0.0) vertical = vec3(0.0, 2.0, 0.0) u = horizontal * rdir.x v = vertical * rdir.y direction = lower_left_corner + u + v iray = ray(origin, direction) colorRet = color(iray) print("Took %s" % (time.time() - t0)) from PIL import Image rgb = [ Image.fromarray( (255 * np.clip(c, 0, 1).reshape(ny, nx)).astype(np.uint8), "L") for c in colorRet.components() ] Image.merge("RGB", rgb).save("output/output_simpleRayCast.png")
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 get_ray(self, u, v): nu = self.horz * u nv = self.vert * v l = nu.components()[0].shape ox = np.repeat(self.origin.x, l) oy = np.repeat(self.origin.y, l) oz = np.repeat(self.origin.z, l) no = vec3(ox, oy, oz) direction = self.llc + nu + nv - no return ray(no, direction)
def main(): t0 = time.time() nx = 200 ny = 100 # Build array of vectors defined on a normalized plane # aspect ratio r = float(nx) / float(ny) # normalized range S = (0., 1., 1., 0.) # linearly step through each xy pixel and create vector position npx = np.tile(np.linspace(S[0], S[2], nx), ny) npy = np.repeat(np.linspace(S[1], S[3], ny), nx) npz = np.repeat(0.0, (nx * ny)) origin = vec3(0.0, 0.0, 0.0) # test = ray(origin, lower_left_corner + npx*horizontal + npy*vertical) # print(test) Q = vec3(npx, npy, npz) rdir = Q - origin lower_left_corner = vec3(-2.0, -1.0, -1.0) horizontal = vec3(4.0, 0.0, 0.0) vertical = vec3(0.0, 2.0, 0.0) u = horizontal * rdir.x v = vertical * rdir.y direction = lower_left_corner + u + v iray = ray(origin, direction) colorRet = color(iray) print("Took %s" % (time.time() - t0)) output_image(colorRet, nx, ny)
def dispverts_of(self, face): # add format argument (lightmap uv, 2 uvs, etc) """vertex format [Position, Normal, TexCoord, LightCoord, Colour] normal is inherited from face returns rows, not tris""" verts = self.verts_of(face) if face.disp_info == -1: raise RuntimeError('face is not a displacement!') if len(verts) != 4: raise RuntimeError( 'face does not have 4 corners (probably t-junctions)') disp_info = self.DISP_INFO[face.disp_info] start = list(disp_info.start_position) start = [round(x, 1) for x in start] # approximate match round_verts = [] for vert in [v[0] for v in verts]: round_verts.append([round(x, 1) for x in vert]) if start in round_verts: # "rotate" index = round_verts.index(start) verts = verts[index:] + verts[:index] A, B, C, D = [vector.vec3(*v[0]) for v in verts] Auv, Buv, Cuv, Duv = [vector.vec2(*v[2]) for v in verts] Auv2, Buv2, Cuv2, Duv2 = [vector.vec2(*v[3]) for v in verts] # scale is wrong AD = D - A ADuv = Duv - Auv ADuv2 = Duv2 - Auv2 BC = C - B BCuv = Cuv - Buv BCuv2 = Cuv2 - Buv2 power2 = 2**disp_info.power full_power = (power2 + 1)**2 start = disp_info.disp_vert_start stop = disp_info.disp_vert_start + full_power new_verts, uvs, uv2s = [], [], [] for index, disp_vert in enumerate(self.DISP_VERTS[start:stop]): t1 = index % (power2 + 1) / power2 t2 = index // (power2 + 1) / power2 bary_vert = vector.lerp(A + (AD * t1), B + (BC * t1), t2) disp_vert = [x * disp_vert.distance for x in disp_vert.vector] new_verts.append([a + b for a, b in zip(bary_vert, disp_vert)]) uvs.append(vector.lerp(Auv + (ADuv * t1), Buv + (BCuv * t1), t2)) uv2s.append( vector.lerp(Auv2 + (ADuv2 * t1), Buv2 + (BCuv2 * t1), t2)) normal = [verts[0][1]] * full_power colour = [verts[0][4]] * full_power verts = list(zip(new_verts, normal, uvs, uv2s, colour)) return verts
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 # push out of the plane, without changing velocity self.position += math.fsum([plane.distance, -p ]) * plane.normal # reset jump? (45 degree check) if vector.dot(plane.normal, vector.vec3(z=1)) <= math.sqrt(2): 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 worldPP(): nx = 400 ny = 300 # Build array of vectors defined on a normalized plane # aspect ratio r = float(nx) / float(ny) # normalized range S = (-1., 1. / r + .25, 1., -1. / r + .25) # linearly step through each xy pixel and create vector position npx = np.tile(np.linspace(S[0], S[2], nx), ny) npy = np.repeat(np.linspace(S[1], S[3], ny), nx) npz = np.repeat(0.2, (nx * ny)) baseColor = vec3(npx, npy, npz) gradientColor = makeGradient(baseColor) from PIL import Image rgb = [ Image.fromarray( (255 * np.clip(c, 0, 1).reshape(ny, nx)).astype(np.uint8), "L") for c in gradientColor.components() ] Image.merge("RGB", rgb).save("output_02.png")
def obj_grouped_objects(filepath): """positions & groupings only""" file = open(filepath) g = ["group0"] # (name, object_name1, ...) groups = [] o = ["object0", 0, 0] # ^ (name, start, end) objects = {} # ^ {name: (start, end)} v = [] vertices = [] indices = [] for line in file.readlines(): line = line[:-1] if line.startswith("g"): groups.append(g) g = [" ".join(line.split()[1:])] elif line.startwith("o"): objects[o[0]] = o[1:] o = [" ".join(line.split()[1:]), o[2] + 1, 0] g.append(o[0]) elif line.startswith("v"): v.append([float(f) for f in line.split(" ")[1:]]) elif line.startswith("f"): line = line.split(" ")[1:] if len(line) == 4: # QUADS ONLY! for neighbour map for point in line: vertex = v[int(point.split("/")[0]) - 1] vertex = vector.vec3(*vertex) # NOTE: slows exponentially [ O(n) ] if vertex not in vertices: vertices.append(vertex) indices.append(len(vertices) - 1) else: indices.append(vertices.index(vertex)) o[2] += 1 return vertices, indices, objects, groups
def main(): t0 = time.time() nx = 600 ny = 300 # world = [Sphere(vec3(0, 0, -1), 0.5, lambertian(0.5)), Sphere(vec3(0, -100.5, -1), 100, lambertian(0.5)), Sphere(vec3(0.75, 0, -1), 0.25, metal(0.5))] world = [ Sphere(vec3(0, 0, -1), 0.5, lambertian(0.5)), Sphere(vec3(0, -100.5, -1), 100, lambertian(0.5)) ] # world = [Sphere(vec3(0, -100.5, -1), 100, lambertian(0.5))] # Build array of vectors defined on a normalized plane # aspect ratio # ratio = float(nx) / float(ny) # normalized range S = (0., 1., 1., 0.) # linearly step through each xy pixel and create vector position npx = np.tile(np.linspace(S[0], S[2], nx), ny) npy = np.repeat(np.linspace(S[1], S[3], ny), nx) npz = np.repeat(0.0, (nx * ny)) origin = vec3(0.0, 0.0, 0.0) color = vec3(0, 0, 0) cam = camera() # print(test) Q = vec3(npx, npy, npz) rdir = Q - origin ns = 1 for s in range(ns): u = rdir.x + (random.random() / float(nx)) v = rdir.y + (random.random() / float(ny)) r = cam.get_ray(u, v) # p = r.point_at_parameter(2.0) color += raytrace(r, world, 0) color = color / vec3(ns, ns, ns) # color = vec3(np.sqrt(color.x), np.sqrt(color.y), np.sqrt(color.z)) print("Took %s" % (time.time() - t0)) output_image(color, nx, ny)
def reset(self): """reset all camera state to default values""" # reset camera's position and orientation self.resetLocalSpace() # "look at" point, center of view self.target = vec3(0.0) # vehicle being tracked self.vehicleToTrack = None # aim at predicted position of vehicleToTrack, this far into thefuture self.aimLeadTime = 1.0 # make first update abrupt self.smoothNextMove = False # relative rate at which camera transitions proceed self.smoothMoveSpeed = 1.5 # select camera aiming mode self.mode = cmFixed # "constant distance from vehicle" camera mode parameters self.fixedDistDistance = 1.0 self.fixedDistVOffset = 0.0 # "look straight down at vehicle" camera mode parameters self.lookdownDistance = 30 # "static" camera mode parameters self.fixedPosition = vec3(75.0, 75.0, 75.0) self.fixedTarget = vec3(0.0) self.fixedUp = vec3(vector.up) # "fixed local offset" camera mode parameters self.fixedLocalOffset = vec3(5.0, 5.0, -5.0) # "offset POV" camera mode parameters self.povOffset = vec3(0.0, 1.0, -3.0)
---------------------------------------------------------------------------- PyOpenSteer -- Port of OpenSteer to Python Copyright (c) 2004 Lutz Paelike <*****@*****.**> The license follows the original Opensteer license but must include this additional copyright notice. ---------------------------------------------------------------------------- """ from vector import vec3 gBlack = vec3(0, 0, 0) gWhite = vec3(1, 1, 1) gRed = vec3(1, 0, 0) gYellow = vec3(1, 1, 0) gGreen = vec3(0, 1, 0) gCyan = vec3(0, 1, 1) gBlue = vec3(0, 0, 1) gMagenta = vec3(1, 0, 1) gOrange = vec3(1, 0.5, 0) gGray10 = vec3(0.1) gGray20 = vec3(0.2) gGray30 = vec3(0.3) gGray40 = vec3(0.4)
def __init__(self): self.llc = vec3(-2.0, -1.0, -1.0) self.horz = vec3(4.0, 0.0, 0.0) self.vert = vec3(0.0, 2.0, 0.0) self.origin = vec3(0.0, 0.0, 0.0)
def main(width, height, bsp): SDL_Init(SDL_INIT_VIDEO) window = SDL_CreateWindow(bytes(bsp.filename, 'utf-8'), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS) #SDL_WINDOW_FULLSCREEN glContext = SDL_GL_CreateContext(window) glColor(0, 0, 0, 0) gluPerspective(90, width / height, 0.1, 4096 * 4) glPointSize(2) glPolygonMode(GL_BACK, GL_LINE) glEnable(GL_DEPTH_TEST) glColor(1, 1, 1) glFrontFace(GL_CW) FACE = iter(bsp.FACES) current_face = next(FACE) current_face_verts = bsp.verts_of(current_face) all_faces = [] all_faces_map = [] start = 0 for face in bsp.FACES: if face['dispinfo'] == -1: f_verts = bsp.verts_of(face) out = f_verts[:3] f_verts = f_verts[3:] for vert in f_verts: out += [out[0], out[-1], vert] f_verts = out f_verts_len = len(f_verts) all_faces_map.append((start, f_verts_len)) start += f_verts_len else: power = bsp.DISP_INFO[face['dispinfo']]['power'] f_verts = bsp_tool.disp_tris(bsp.dispverts_of(face), power) all_faces += f_verts ## all_faces = list(itertools.chain(*all_faces)) NODE = iter(filter(lambda x: x['children'][1] < 0, bsp.NODES)) NODE = sorted(bsp.NODES, key=lambda node: sum( [x[1] for x in node_faces(node, bsp, all_faces_map)])) current_node = NODE[0] current_node_index = 0 draw_calls = node_faces(current_node, bsp, all_faces_map) current_node_aabb = aabb(current_node['mins'], current_node['maxs']) cnff = current_node['firstface'] current_node_faces = all_faces_map[cnff:cnff + current_node['numfaces']] try: cn_start = current_node_faces[0][0] cn_count = sum([x[1] for x in current_node_faces]) except: cn_start = 0 cn_count = 0 all_nodes = list(map(lambda x: aabb(x['mins'], x['maxs']), bsp.NODES)) all_leaves = list(map(lambda x: aabb(x['mins'], x['maxs']), bsp.LEAVES)) print(bsp.filename.upper(), end=' ') print('{:,}KB BSP'.format(bsp.bytesize // 1024), '>>>', end=' ') print('{:,} TRIS'.format(len(all_faces) // 9), end=' & ') print('{:,}KB VRAM'.format((len(all_faces) * 4) // 1024)) print('{:,} NODES'.format(len(bsp.NODES))) # shader & vertex buffer would go here SDL_GL_SetSwapInterval(0) SDL_CaptureMouse(SDL_TRUE) SDL_WarpMouseInWindow(window, width // 2, height // 2) SDL_SetRelativeMouseMode(SDL_TRUE) SDL_SetWindowGrab(window, SDL_TRUE) cam_spawn = vector.vec3(0, 0, 0) init_speed = 128 VIEW_CAMERA = camera.freecam(cam_spawn, None, init_speed) mousepos = vector.vec2() keys = [] tickrate = 120 event = SDL_Event() oldtime = time() 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: if event.key.keysym.sym not in keys: 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: mousepos += vector.vec2(event.motion.xrel, event.motion.yrel) SDL_WarpMouseInWindow(window, width // 2, height // 2) if event.type == SDL_MOUSEWHEEL: VIEW_CAMERA.speed += event.wheel.y * 32 if event.type == SDL_MOUSEBUTTONDOWN: if event.button.button not in keys: keys.append(event.button.button) if event.type == SDL_MOUSEBUTTONUP: while event.button.button in keys: keys.remove(event.button.button) dt = time() - oldtime while dt >= 1 / tickrate: VIEW_CAMERA.update(mousepos, keys, 1 / tickrate) if SDLK_BACKQUOTE in keys: #NODES print(current_node, draw_calls, sep='\n\n') cn_center = (current_node_aabb.mins + current_node_aabb.maxs) / 2 VIEW_CAMERA.position = cn_center while SDLK_BACKQUOTE in keys: keys.remove(SDLK_BACKQUOTE) if SDLK_r in keys: VIEW_CAMERA = camera.freecam(cam_spawn, None, init_speed) if SDLK_LSHIFT in keys: VIEW_CAMERA.speed += VIEW_CAMERA.speed * .125 if SDLK_LCTRL in keys: VIEW_CAMERA.speed -= VIEW_CAMERA.speed * .125 if SDLK_LEFT in keys or SDL_BUTTON_LEFT in keys: current_node_index -= 1 current_node = NODE[current_node_index] draw_calls = node_faces(current_node, bsp, all_faces_map) current_node_aabb = aabb(current_node['mins'], current_node['maxs']) VIEW_CAMERA.position = current_node_aabb.center cnff = current_node['firstface'] current_node_faces = all_faces_map[cnff:cnff + current_node['numfaces']] try: cn_start = current_node_faces[0][0] cn_count = sum([x[1] for x in current_node_faces]) except: cn_start = 0 cn_count = 0 while SDLK_LEFT in keys: keys.remove(SDLK_LEFT) while SDL_BUTTON_LEFT in keys: keys.remove(SDL_BUTTON_LEFT) if SDLK_RIGHT in keys or SDL_BUTTON_RIGHT in keys: current_node_index += 1 current_node = NODE[current_node_index] draw_calls = node_faces(current_node, bsp, all_faces_map) current_node_aabb = aabb(current_node['mins'], current_node['maxs']) VIEW_CAMERA.position = current_node_aabb.center cnff = current_node['firstface'] current_node_faces = all_faces_map[cnff:cnff + current_node['numfaces']] try: cn_start = current_node_faces[0][0] cn_count = sum([x[1] for x in current_node_faces]) except: cn_start = 0 cn_count = 0 while SDLK_RIGHT in keys: keys.remove(SDLK_RIGHT) while SDL_BUTTON_RIGHT in keys: keys.remove(SDL_BUTTON_RIGHT) dt -= 1 / tickrate oldtime = time() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glPushMatrix() VIEW_CAMERA.set() glPolygonMode(GL_FRONT, GL_LINE) ## glUseProgram(0) glColor(1, 0, 1) glBegin(GL_LINES) current_node_aabb.draw() glEnd() glColor(1, 1, 1) glDrawArrays(GL_TRIANGLES, cn_start, cn_count) ## glUseProgram(bsp_shader) glColor(1, .5, 0) glPolygonMode(GL_FRONT, GL_FILL) glPolygonMode(GL_BACK, GL_LINE) try: for draw_call in draw_calls: glDrawArrays(GL_TRIANGLES, draw_call[0], draw_call[1]) except: pass #CENTER POINT ## glUseProgram(0) ## glBegin(GL_LINES) ## glColor(1, 0, 0) ## glVertex(0, 0, 0) ## glVertex(128, 0, 0) ## glColor(0, 1, 0) ## glVertex(0, 0, 0) ## glVertex(0, 128, 0) ## glColor(0, 0, 1) ## glVertex(0, 0, 0) ## glVertex(0, 0, 128) ## glEnd() glPopMatrix() SDL_GL_SwapWindow(window)
def drawReticle(): """ draw a reticle at the center of the window. Currently it is small crosshair with a gap at the center, drawn in white with black borders """ a = 10; b = 30; w = glutGet(GLUT_WINDOW_WIDTH) * 0.5 h = glutGet(GLUT_WINDOW_HEIGHT) * 0.5 draw2dLine(vec3 (w+a, h, 0), vec3 (w+b, h, 0), gWhite) draw2dLine(vec3 (w, h+a, 0), vec3 (w, h+b, 0), gWhite) draw2dLine(vec3 (w-a, h, 0), vec3 (w-b, h, 0), gWhite) draw2dLine(vec3 (w, h-a, 0), vec3 (w, h-b, 0), gWhite) glLineWidth(3) draw2dLine(vec3 (w+a, h, 0), vec3 (w+b, h, 0), gBlack) draw2dLine(vec3 (w, h+a, 0), vec3 (w, h+b, 0), gBlack) draw2dLine(vec3 (w-a, h, 0), vec3 (w-b, h, 0), gBlack) draw2dLine(vec3 (w, h-a, 0), vec3 (w, h-b, 0), gBlack) glLineWidth(1)
def drawDisplayPlugInName(): h = glutGet(GLUT_WINDOW_HEIGHT) screenLocation = vec3(10, h-20, 0) draw2dTextAt2dLocation("Python Plugin", screenLocation, gWhite)
def drawDisplayCameraModeName(): """raw camera mode name in lower lefthand corner of screen""" message = "Camera %s\n" % (SteerTest.camera.modeName()) screenLocation =vec3(10, 10, 0) draw2dTextAt2dLocation(message, screenLocation, gWhite)
def drawCircleOrDisk(radius, axis, center, color, segments, filled, in3d=True): """ General purpose circle/disk drawing routine. Draws circles or disks (as specified by "filled" argument) and handles both special case 2d circles on the XZ plane or arbitrary circles in 3d space (as specified by "in3d" argument) """ ls = LocalSpace() if (in3d): # define a local space with "axis" as the Y/up direction # (XXX should this be a method on LocalSpace?) unitAxis = axis.normalize() unitPerp = findPerpendicularIn3d(axis).normalize() ls.setUp(unitAxis) ls.setForward(unitPerp) ls.setPosition(center) ls.setUnitSideFromForwardAndUp() # make disks visible (not culled) from both sides if (filled): beginDoubleSidedDrawing() # point to be rotated about the (local) Y axis, angular step size pointOnCircle = vec3(radius, 0, 0) step = (2 * M_PI) / segments # set drawing color glColor3f(color.x, color.y, color.z) # begin drawing a triangle fan (for disk) or line loop (for circle) if filled: glBegin (GL_TRIANGLE_FAN) # for the filled case, first emit the center point if in3d: iglVertexVec3(ls.position()) else: iglVertexVec3(center) vertexCount = segments+1 else: glBegin (GL_LINE_LOOP) vertexCount = segments # rotate p around the circle in "segments" steps sin=0.0 cos=0.0 for i in range(vertexCount): # emit next point on circle, either in 3d (globalized out # of the local space), or in 2d (offset from the center) if in3d: iglVertexVec3(ls.globalizePosition(pointOnCircle)) else: iglVertexVec3((pointOnCircle + center)) # rotate point one more step around circle # LP: changed interface to the python way pointOnCircle, sin, cos = pointOnCircle.rotateAboutGlobalY(step, sin, cos) # close drawing operation glEnd() if (filled): endDoubleSidedDrawing()