def calculate_bbox(self): p0 = Vector3(9999999.0, 9999999.0, 9999999.0) p1 = Vector3(-9999999.0, -9999999.0, -9999999.0) self.bounding_box = renmas.shapes.BBox(p0, p1, None) for i in range(self.ntriangles()): v0, v1, v2 = self.triangles.get_vertices(i) extend_bbox(self.vertex_buffer, v0, v1, v2, self.bounding_box)
def create_triangle(): p0 = Vector3(1.1, 0.0, 0.0) p1 = Vector3(4.0, 0.5, 0.2) p2 = Vector3(2.5, 4.3, 0.4) tr = Triangle(p0, p1, p2, 3) return tr
def intersect_sphere(runtime, ds): sphere = Sphere(Vector3(0.0, 0.0, 0.0), 1.5, 2) direction = Vector3(-7.0, -7.0, -6.0) direction.normalize() ray = Ray(Vector3(8.0, 7.0, 6.0), direction) ds["sph.origin"] = v4(sphere.origin) ds["sph.radius"] = sphere.radius ds["sph.mat_index"] = sphere.material ds["r1.origin"] = v4(ray.origin) ds["r1.dir"] = v4(ray.dir) hp = sphere.intersect(ray, 999999.0) runtime.run("test") if hp is not False: print(hp.t, ds["t"], ds["hit"]) print("Python =", hp.t, "Asm = ", ds["hp.t"]) print("Python =", hp.hit_point) print("Asm =", ds["hp.hit"]) print("Python =", hp.normal) print("Asm =", ds["hp.normal"]) print("Python = ", hp.material, " ASM = ", ds["hp.mat_index"]) #print(ds["a"], ds["b"], ds["disc"], ds["temp"]) else: print(hp, ds["hit"])
def create_triangle(): p0 = Vector3(0.1, 0.0, -2.0) p1 = Vector3(4.0, 0.5, 0.2) p2 = Vector3(2.2, 4.3, -1.0) tr = Triangle(p0, p1, p2, 3) return tr
def __init__(self, material): self.triangles = None self.vertex_buffer = None self.material = material #default material p0 = Vector3(9999999.0, 9999999.0, 9999999.0) p1 = Vector3(-9999999.0, -9999999.0, -9999999.0) import renmas.shapes self.bounding_box = renmas.shapes.BBox(p0, p1, None) self.grid = None self.ptr_isect = None
def create_ray(): origin = Vector3(0.0, 0.0, 0.0) dirx = 0.985906665972 diry = 0.165777376892 dirz = 0.0224923832256 #direction = Vector3(8.8, 8.9, 8.7) direction = Vector3(dirx, diry, dirz) #direction.normalize() ray = Ray(origin, direction) return ray
def get_triangle(self, idx): v0, v1, v2 = self.triangles.get_vertices(idx) vb = self.vertex_buffer p0 = vb.get_position(v0) p1 = vb.get_position(v1) p2 = vb.get_position(v2) ver0 = Vector3(p0[0], p0[1], p0[2]) ver1 = Vector3(p1[0], p1[1], p1[2]) ver2 = Vector3(p2[0], p2[1], p2[2]) tri = renmas.shapes.Triangle(ver0, ver1, ver2, self.triangles.get_material(idx)) return tri
def generate_ray(): x = 7.0 y = 6.0 z = 5.5 dir_x = 10.0 dir_y = 10.0 dir_z = 10.0 origin = Vector3(x, y, z) direction = Vector3(dir_x, dir_y, dir_z) direction.normalize() ray = Ray(origin, direction) return ray
def generate_ray(): x = random.random() * 10.0 y = random.random() * 10.0 z = random.random() * 10.0 dir_x = random.random() * 10.0 - 5.0 dir_y = random.random() * 10.0 - 5.0 dir_z = random.random() * 10.0 - 5.0 origin = Vector3(x, y, z) direction = Vector3(dir_x, dir_y, dir_z) direction.normalize() ray = Ray(origin, direction) return ray
def lst_triangles(self): lst = [] for i in range(self.ntriangles()): v0, v1, v2 = self.triangles.get_vertices(i) vb = self.vertex_buffer p0 = vb.get_position(v0) p1 = vb.get_position(v1) p2 = vb.get_position(v2) ver0 = Vector3(p0[0], p0[1], p0[2]) ver1 = Vector3(p1[0], p1[1], p1[2]) ver2 = Vector3(p2[0], p2[1], p2[2]) tri = renmas.shapes.Triangle(ver0, ver1, ver2, self.triangles.get_material(i)) lst.append(tri) return lst
def bbox(self): epsilon = 0.001 p0X = self.origin.x - self.radius - epsilon p0Y = self.origin.y - self.radius - epsilon p0Z = self.origin.z - self.radius - epsilon p1X = self.origin.x + self.radius + epsilon p1Y = self.origin.y + self.radius + epsilon p1Z = self.origin.z + self.radius + epsilon p0 = Vector3(p0X, p0Y, p0Z) p1 = Vector3(p1X, p1Y, p1Z) return BBox(p0, p1, None)
def generate_plane(): x = random.random() * 10.0 y = random.random() * 10.0 z = random.random() * 10.0 dir_x = random.random() * 10.0 - 5.0 dir_y = random.random() * 10.0 - 5.0 dir_z = random.random() * 10.0 - 5.0 point = Vector3(x, y, z) normal = Vector3(dir_x, dir_y, dir_z) normal.normalize() plane = Plane(point, normal, 3) return plane
def generate_sphere(): x = random.random() * 10.0 - 5.0 y = random.random() * 10.0 - 5.0 z = random.random() * 10.0 - 5.0 radius = random.random() * 10.0 sphere = Sphere(Vector3(x, y, z), radius, 2) return sphere
def bbox_tri(self, idx): v0, v1, v2 = self.triangles.get_vertices(idx) vb = self.vertex_buffer p0 = vb.get_position(v0) p1 = vb.get_position(v1) p2 = vb.get_position(v2) epsilon = 0.0001 minx = min(min(p0[0], p1[0]), p2[0]) - epsilon maxx = max(max(p0[0], p1[0]), p2[0]) + epsilon miny = min(min(p0[1], p1[1]), p2[1]) - epsilon maxy = max(max(p0[1], p1[1]), p2[1]) + epsilon minz = min(min(p0[2], p1[2]), p2[2]) - epsilon maxz = max(max(p0[2], p1[2]), p2[2]) + epsilon p0 = Vector3(minx, miny, minz) p1 = Vector3(maxx, maxy, maxz) return renmas.shapes.BBox(p0, p1, 99999) #material undefined #TODO fix BBox implement Box
def random_sphere(): x = 0.0 y = 0.0 z = 0.0 radius = 3.0 v1 = Vector3(x, y, z) sphere = Sphere(v1, radius, 99999) return sphere
def get_normal(self, face): if face == 0: return Vector3(-1.0, 0.0, 0.0) elif face == 1: return Vector3(0.0, -1.0, 0.0) elif face == 2: return Vector3(0.0, 0.0, -1.0) elif face == 3: return Vector3(1.0, 0.0, 0.0) elif face == 4: return Vector3(0.0, 1.0, 0.0) elif face == 5: return Vector3(0.0, 0.0, 1.0)
def create_triangle_array(n): lst_arr = [] dy = util.DynamicArray(Triangle.struct()) for x in range(n): p0 = Vector3(random.random() * 10.0 - 5.0, random.random() * 10 - 5.0, random.random() * 10 - 5.0) p1 = Vector3(random.random() * 10.0 - 5.0, random.random() * 10 - 5.0, random.random() * 10 - 5.0) p2 = Vector3(random.random() * 10.0 - 5.0, random.random() * 10 - 5.0, random.random() * 10 - 5.0) tr = Triangle(p0, p1, p2, 4) lst_arr.append(tr) dy = util.DynamicArray(Triangle.struct(), len(lst_arr)) for sh in lst_arr: dy.add_instance(sh.attributes()) return dy, lst_arr
def setup(self, mesh): self.mesh = mesh p0 = Vector3(9999999.0, 9999999.0, 9999999.0) p1 = Vector3(-9999999.0, -9999999.0, -9999999.0) bb_min = BBox(p0, p1, None) ntriangles = mesh.ntriangles() #get number of triangles self.bbox = mesh.bbox() #get bounding box around mesh bb_min = self.bbox num_shapes = ntriangles wx = bb_min.x1 - bb_min.x0 wy = bb_min.y1 - bb_min.y0 wz = bb_min.z1 - bb_min.z0 multiplier = 1.3 # about 8 times more cells than objects ako stavimo faktor 2 TODO test this! s = math.pow(wx * wy * wz / float(num_shapes), 0.333333) nx = int(multiplier * wx / s + 1) ny = int(multiplier * wy / s + 1) nz = int(multiplier * wz / s + 1) self.nx = nx self.ny = ny self.nz = nz num_cells = int(nx * ny * nz) print("wx=", wx, " wy=", wy, " wz=", wz) print("nx=", nx, " ny=", ny, " nz=", nz) # every cell have referencs to objects that are in that cell self.cells = [] # we need to initialize empty lists for c in range(num_cells): self.cells.append([]) max_len = 0 num_arrays = 0 num_objects = 0 for idx_triangle in range(ntriangles): bbox = mesh.bbox_tri(idx_triangle) ixmin = int( clamp((bbox.x0 - bb_min.x0) * nx / (bb_min.x1 - bb_min.x0), 0, nx - 1)) iymin = int( clamp((bbox.y0 - bb_min.y0) * ny / (bb_min.y1 - bb_min.y0), 0, ny - 1)) izmin = int( clamp((bbox.z0 - bb_min.z0) * nz / (bb_min.z1 - bb_min.z0), 0, nz - 1)) ixmax = int( clamp((bbox.x1 - bb_min.x0) * nx / (bb_min.x1 - bb_min.x0), 0, nx - 1)) iymax = int( clamp((bbox.y1 - bb_min.y0) * ny / (bb_min.y1 - bb_min.y0), 0, ny - 1)) izmax = int( clamp((bbox.z1 - bb_min.z0) * nz / (bb_min.z1 - bb_min.z0), 0, nz - 1)) #print("x = ", ixmin, ixmax) #print("y = ", iymin, iymax) #print("z = ", izmin, izmax) for k in range(izmin, izmax + 1): for j in range(iymin, iymax + 1): for i in range(ixmin, ixmax + 1): idx = i + nx * j + nx * ny * k self.cells[idx].append(idx_triangle) duzina = len(self.cells[idx]) num_objects += 1 if duzina == 1: num_arrays += 1 if duzina > max_len: max_len = duzina nx_1 = float(self.nx - 1) ny_1 = float(self.ny - 1) nz_1 = float(self.nz - 1) self.n_1 = Vector3(nx_1, ny_1, nz_1) ovx = 1.0 / self.nx ovy = 1.0 / self.ny ovz = 1.0 / self.nz self.one_overn = Vector3(ovx, ovy, ovz) nboxx = float(self.nx / (self.bbox.x1 - self.bbox.x0)) nboxy = float(self.ny / (self.bbox.y1 - self.bbox.y0)) nboxz = float(self.nz / (self.bbox.z1 - self.bbox.z0)) self.nbox_width = Vector3(nboxx, nboxy, nboxz) # we must alocate memory 3d grid and arrays self.asm_cells = x86.MemData(num_cells * 4) self.lin_array = x86.MemData( num_arrays * 4 + num_objects * 4 + 4) #we start of index[1] that why extra four bytes x86.SetUInt32(self.lin_array.ptr(), 0, 0) offset = 4 # offset is in bytes for k in range(nz): for j in range(ny): for i in range(nx): idx = i + nx * j + nx * ny * k cell = self.cells[idx] if len(cell) == 0: adr = self.asm_cells.ptr() adr = adr + idx * 4 x86.SetUInt32(adr, 0, 0) else: adr = self.asm_cells.ptr() adr = adr + idx * 4 x86.SetUInt32(adr, offset, 0) adr = self.lin_array.ptr() adr += offset num = len(cell) x86.SetUInt32(adr, num, 0) offset += 4 x86.SetUInt32(adr + 4, tuple(cell), 0) offset = offset + len(cell) * 4 print("Najduzi niz je", duzina) return None
def create_ray(): origin = Vector3(0.0, 0.0, 0.0) direction = Vector3(8.8, 8.9, 8.7) direction.normalize() ray = Ray(origin, direction) return ray
def ray_tri(self, ray, idx, min_dist = 999999.0): v0, v1, v2 = self.triangles.get_vertices(idx) vb = self.vertex_buffer p0 = vb.get_position(v0) p1 = vb.get_position(v1) p2 = vb.get_position(v2) a = p0[0] - p1[0] b = p0[0] - p2[0] c = ray.dir.x d = p0[0] - ray.origin.x e = p0[1] - p1[1] f = p0[1] - p2[1] g = ray.dir.y h = p0[1] - ray.origin.y i = p0[2] - p1[2] j = p0[2] - p2[2] k = ray.dir.z l = p0[2] - ray.origin.z m = f * k - g * j n = h * k - g * l p = f * l - h * j q = g * i - e * k s = e * j - f * i temp3 = (a * m + b * q + c * s) if temp3 == 0.0: return False inv_denom = 1.0 / temp3 e1 = d * m - b * n - c * p beta = e1 * inv_denom if beta < 0.0: return False r = e * l - h * i e2 = a * n + d * q + c * r gamma = e2 * inv_denom if gamma < 0.0: return False if beta + gamma > 1.0: return False e3 = a * p - b * r + d * s t = e3 * inv_denom if t < 0.00001: return False # self-intersection hit_point = ray.origin + ray.dir * t #temp = self.triangles.get_normal(idx) #normal = Vector3(temp[0], temp[1], temp[2]) temp1 = vb.get_normal(v0) temp2 = vb.get_normal(v1) temp3 = vb.get_normal(v2) normal1 = Vector3(temp1[0], temp1[1], temp1[2]) normal2 = Vector3(temp2[0], temp2[1], temp2[2]) normal3 = Vector3(temp3[0], temp3[1], temp3[2]) normal = normal1 * (1.0-beta-gamma) + normal2*beta + normal3*gamma normal.normalize() return renmas.shapes.HitPoint(t, hit_point, normal, self.triangles.get_material(idx), ray)
def setup(self, shapes, ren=None): p0 = Vector3(9999999.0, 9999999.0, 9999999.0) p1 = Vector3(-9999999.0, -9999999.0, -9999999.0) bb_min = BBox(p0, p1, None) for shape in shapes: bbox = shape.bbox() if bbox.x0 < bb_min.x0: bb_min.x0 = bbox.x0 if bbox.y0 < bb_min.y0: bb_min.y0 = bbox.y0 if bbox.z0 < bb_min.z0: bb_min.z0 = bbox.z0 if bbox.x1 > bb_min.x1: bb_min.x1 = bbox.x1 if bbox.y1 > bb_min.y1: bb_min.y1 = bbox.y1 if bbox.z1 > bb_min.z1: bb_min.z1 = bbox.z1 self.bbox = bb_min num_shapes = len(shapes) #FIXME when we incoorporate mesh wx = bb_min.x1 - bb_min.x0 wy = bb_min.y1 - bb_min.y0 wz = bb_min.z1 - bb_min.z0 multiplier = 1.3 # about 8 times more cells than objects TODO test this! s = math.pow(wx * wy * wz / float(num_shapes), 0.333333) nx = int(multiplier * wx / s + 1) ny = int(multiplier * wy / s + 1) nz = int(multiplier * wz / s + 1) self.nx = nx self.ny = ny self.nz = nz num_cells = int(nx * ny * nz) print("wx=", wx, " wy=", wy, " wz=", wz) print("nx=", nx, " ny=", ny, " nz=", nz) # every cell have referencs to objects that are in that cell self.cells = [] # we need to initialize list for c in range(num_cells): self.cells.append([]) max_len = 0 num_arrays = 0 num_objects = 0 for shape in shapes: bbox = shape.bbox() ixmin = int( clamp((bbox.x0 - bb_min.x0) * nx / (bb_min.x1 - bb_min.x0), 0, nx - 1)) iymin = int( clamp((bbox.y0 - bb_min.y0) * ny / (bb_min.y1 - bb_min.y0), 0, ny - 1)) izmin = int( clamp((bbox.z0 - bb_min.z0) * nz / (bb_min.z1 - bb_min.z0), 0, nz - 1)) ixmax = int( clamp((bbox.x1 - bb_min.x0) * nx / (bb_min.x1 - bb_min.x0), 0, nx - 1)) iymax = int( clamp((bbox.y1 - bb_min.y0) * ny / (bb_min.y1 - bb_min.y0), 0, ny - 1)) izmax = int( clamp((bbox.z1 - bb_min.z0) * nz / (bb_min.z1 - bb_min.z0), 0, nz - 1)) #print("x = ", ixmin, ixmax) #print("y = ", iymin, iymax) #print("z = ", izmin, izmax) for k in range(izmin, izmax + 1): for j in range(iymin, iymax + 1): for i in range(ixmin, ixmax + 1): idx = i + nx * j + nx * ny * k self.cells[idx].append(shape) duzina = len(self.cells[idx]) num_objects += 1 if duzina == 1: num_arrays += 1 if duzina > max_len: max_len = duzina nx_1 = float(self.nx - 1) ny_1 = float(self.ny - 1) nz_1 = float(self.nz - 1) self.n_1 = Vector3(nx_1, ny_1, nz_1) ovx = 1.0 / self.nx ovy = 1.0 / self.ny ovz = 1.0 / self.nz self.one_overn = Vector3(ovx, ovy, ovz) nboxx = float(self.nx / (self.bbox.x1 - self.bbox.x0)) nboxy = float(self.ny / (self.bbox.y1 - self.bbox.y0)) nboxz = float(self.nz / (self.bbox.z1 - self.bbox.z0)) self.nbox_width = Vector3(nboxx, nboxy, nboxz) # we must alocate memory 3d grid and arrays self.asm_cells = x86.MemData(num_cells * 4) self.lin_array = x86.MemData( num_arrays * 4 + num_objects * 8 + 4) #we start of index[1] that why extra four bytes x86.SetUInt32(self.lin_array.ptr(), 0, 0) offset = 4 # offset is in bytes self.runtime = runtime = Runtime() for k in range(nz): for j in range(ny): for i in range(nx): idx = i + nx * j + nx * ny * k cell = self.cells[idx] if len(cell) == 0: adr = self.asm_cells.ptr() adr = adr + idx * 4 x86.SetUInt32(adr, 0, 0) else: adr = self.asm_cells.ptr() adr = adr + idx * 4 x86.SetUInt32(adr, offset, 0) adr = self.lin_array.ptr() adr += offset num = len(cell) x86.SetUInt32(adr, num, 0) offset += 4 if ren is None: lst_address = renmas.interface.objfunc_array( cell, runtime) else: lst_address = self.objfunc_array( cell, runtime, ren) n = len(lst_address) x86.SetUInt32(adr + 4, lst_address, 0) offset = offset + n * 4 #br = x86.GetUInt32(self.lin_array.ptr(), 0, 30) #print("br", br) #for k in range(nz): # for j in range(ny): # for i in range(nx): # idx = i + nx * j + nx * ny * k # adr = self.asm_cells.ptr() # adr = adr + idx * 4 # br = x86.GetUInt32(adr, 0, 0) # print(k, j, i, idx, br) print("duzina", max_len) print("num objects =", num_objects, " num arrays", num_arrays) return None