Example #1
0
def randomLessThan(throttle: ti.template()):
    if ti.static(isinstance(throttle, (int, float))):
        if ti.static(throttle == 1):
            return True
        if ti.static(throttle == 0):
            return False
    return ti.random() < throttle
Example #2
0
def Reset():
    for i in range(n_particles):
        x[i] = [
            (ti.random() - 0.5) * init_particle_size_x +
            init_particle_center_x,
            (ti.random() - 0.5) * init_particle_size_y +
            init_particle_center_y,
        ]
        v[i] = [0, 0]
        F[i] = ti.Matrix([[1, 0], [0, 1]])
        Jp[i] = 1
        C[i] = ti.Matrix.zero(float, 2, 2)
    gravity[None] = [0, -9.81]
    capsule_translation[None] = [init_capsule_center_x, init_capsule_center_y]
    capsule_trans_vel[None] = [0, init_capsule_vel_y]
    capsule_rotation[None] = [0.0]
Example #3
0
def test_periodic(a, burn_in, target_orbit_length, max_orbit_length):
    x_nought = ti.random(real)
    x_curr = x_nought

    # allow the initial condition to settle into an orbit
    for idx in range(burn_in):
        x_curr = a * x_curr * (1 - x_curr)

    # save first point in the possible orbit
    x_final = x_curr
    period_length = 0
    period_found = False
    # print("x_final", x_final)
    for idx in range(max_orbit_length):
        x_curr = a * x_curr * (1 - x_curr)
        if not period_found:
            period_length += 1

        if (x_curr == x_final):
            period_found = True
    # if (period_length >= target_orbit_length):
    #     print("Period of length", period_length, "found - a:", a)
    if not period_found:
        period_length = 0
    return period_length
Example #4
0
def sample_ray_dir(indir, normal, hit_pos, mat):
    u = ti.Vector([0.0, 0.0, 0.0])
    pdf = 1.0
    if mat == mat_lambertian:
        u = sample_brdf(normal)
        pdf = max(eps, compute_brdf_pdf(normal, u))
    elif mat == mat_specular:
        u = reflect(indir, normal)
    elif mat == mat_glass:
        cos = indir.dot(normal)
        ni_over_nt = refr_idx
        outn = normal
        if cos > 0.0:
            outn = -normal
            cos = refr_idx * cos
        else:
            ni_over_nt = 1.0 / refr_idx
            cos = -cos
        has_refr, refr_dir = refract(indir, outn, ni_over_nt)
        refl_prob = 1.0
        if has_refr:
            refl_prob = schlick(cos, refr_idx)
        if ti.random() < refl_prob:
            u = reflect(indir, normal)
        else:
            u = refr_dir
    return u.normalized(), pdf
Example #5
0
def reset(mode: ti.i32):
    # enforce initial velocity field
    for i in range(n_particles):
        x[i] = [ti.random() * 0.6 + 0.2, ti.random() * 0.6 + 0.2]
        if mode == 0:
            v[i] = [1, 0]
        elif mode == 1:
            v[i] = [x[i][1] - 0.5, 0.5 - x[i][0]]
        elif mode == 2:
            v[i] = [0, x[i][0] - 0.5]
        elif mode == 3:
            v[i] = [0, x[i][1] - 0.5]
        else:
            # Incompressibility is not ensured. Cannot do biaxial??
            if x[i][1] > 0.75:
                v[i] = [0, -0.3]
Example #6
0
def init_particle():

    group_size = n_particle // 3

    for i in particle_position:

        group_id = i // group_size
        particle_material[i] = group_id

        particle_position[i] = (
            ti.Vector([ti.random(), ti.random()]) * 0.25 + 0.1 +
            group_id * 0.26) * length
        particle_velocity[i] = ti.Vector([0.0, -1.0])

        particle_F[i] = ti.Matrix([[1, 0], [0, 1]])
        particle_J[i] = 1.0
Example #7
0
def step(phase: ti.i32):
    # move
    for i in position:
        pos, ang = position[i], heading[i]
        l = sense(phase, pos, ang - SENSE_ANGLE)
        c = sense(phase, pos, ang)
        r = sense(phase, pos, ang + SENSE_ANGLE)
        if l < c < r:
            ang += MOVE_ANGLE
        elif l > c > r:
            ang -= MOVE_ANGLE
        elif c < l and c < r:
            ang += MOVE_ANGLE * (2 * (ti.random() < 0.5) - 1)
        pos += ti.Vector([ti.cos(ang), ti.sin(ang)]) * MOVE_STEP
        position[i], heading[i] = pos, ang

    # deposit
    for i in position:
        ipos = position[i].cast(int) % GRID_SIZE
        grid[phase, ipos] += 1.0

    # diffuse
    for i, j in ti.ndrange(GRID_SIZE, GRID_SIZE):
        a = 0.0
        for di in ti.static(range(-1, 2)):
            for dj in ti.static(range(-1, 2)):
                a += grid[phase, (i + di) % GRID_SIZE, (j + dj) % GRID_SIZE]
        a *= EVAPORATION / 9.0
        grid[1 - phase, i, j] = a
Example #8
0
 def seed_from_voxels(self, material: ti.i32, color: ti.i32,
                      sample_density: ti.i32):
     for i, j, k in self.voxelizer.voxels:
         inside = 1
         for d in ti.static(range(3)):
             inside = inside and self.padding <= i and i < self.res[
                 d] - self.padding
         if inside and self.voxelizer.voxels[i, j, k] > 0:
             for l in range(sample_density):
                 x = ti.Vector(
                     [ti.random() + i,
                      ti.random() + j,
                      ti.random() + k]) * self.dx
                 p = ti.atomic_add(self.n_particles[None], 1)
                 self.seed_particle(p, x, material, color,
                                    self.source_velocity[None])
Example #9
0
    def sample(self, dir, N, t, i, j, mat_buf, mat_id):
        next_dir    = ti.Vector([0.0, 0.0, 0.0])
        w_out       = dir
        cos_theta_i = w_out.dot(N)
        ior         = UF.get_material_ior(mat_buf, mat_id)
        eta         = ior

        probability = ti.random()   
        f_or_b      = 1.0
        R           = probability + 1.0
        extinction  = 1.0

        if (cos_theta_i > 0.0):
            N      = -N
            extinction = ti.exp(-0.1*t)
        else:
            cos_theta_i = -cos_theta_i
            eta = 1.0 /ior
            

        next_dir,suc = self.refract(w_out, N, eta)
        if suc > 0.0:
            R = self.schlick(cos_theta_i, ior)

        if (probability < R):
            next_dir = ts.reflect(w_out, N)
        else:
            f_or_b   = -1.0

        return next_dir, f_or_b*extinction
Example #10
0
 def fill():
     for i in range(n):
         for j in range(n):
             v = ti.random(precision)
             if precision == ti.i32:
                 x[i, j] = (float(v) + float(2**31)) / float(2**32)
             else:
                 x[i, j] = (float(v) + float(2**63)) / float(2**64)
Example #11
0
def create_new_form():
    for i in range(particle_width):
        for j in range(particle_height):
            b[i, j] = a[i, j]
            if(ti.random(type) >0.98):
                b[i, j] = a[i, j]*(-1)
    normalize(b)
    new_hamiltonian[None] = Hamiltonian(b)
Example #12
0
 def radiance(self):
     outdir = ts.vec3(0.0)
     clr = ts.vec3(0.0)
     if ti.random() < self.emission:
         clr = ts.vec3(self.emission_color)
     elif ti.random() < self.specular:
         clr = ts.vec3(self.specular_color)
         outdir = ts.reflect(self.indir, self.normal)
     elif ti.random() < self.diffuse:
         clr = ts.vec3(self.diffuse_color)
         outdir = ts.randUnit3D()
         if outdir.dot(self.normal) < 0:
             outdir = -outdir
         #s = ti.random()
         #outdir = ts.vec3(ti.sqrt(1 - s**2) * ts.randUnit2D(), s)
         #outdir = ti.Matrix.cols([self.tangent, self.bitangent, self.normal]) @ outdir
     return self.pos, outdir, clr
Example #13
0
def init():
    up[None] = [0.0, 1.0, 0.0]
    lookat[None] = [0.0, 0.0, 0.0]
    fov[None] = math.pi / 3
    cam_r[None] = 2.0
    cam_theta[None] = math.pi / 4
    cam_phi[None] = math.pi / 4
    dir_l_theta[None] = math.pi / 4
    dir_l_phi[None] = math.pi / 4

    for i in range(sphere_num):
        sphere_origin_list[i] = ti.Vector(
            [ti.random() * 2 - 1,
             ti.random() * 2 - 1,
             ti.random() * 2 - 1])
        sphere_radius_list[i] = 0.03
        sphere_material_color_list[i] = ti.Vector([1, 1, 1])
Example #14
0
def rand_unit_3d():
    '''
    Uniformly samples a vector on a 3D unit sphere.
    '''
    u = rand_unit_2d()
    s = ti.random() * 2 - 1
    c = ti.sqrt(1 - s**2)
    return ti.Vector([c * u[0], c * u[1], s])
def init():
    vortex[0] = ti.Vector([0, 1])
    vortex[1] = ti.Vector([0, -1])
    vortex[2] = ti.Vector([0, 0.3])
    vortex[3] = ti.Vector([0, -0.3])
    vortex[4] = ti.Vector([0, 0.65])
    vortex[5] = ti.Vector([0, -0.65])

    sign[0] = 1
    sign[1] = -1
    sign[2] = 1
    sign[3] = -1
    sign[4] = 1
    sign[5] = -1

    for i in range(particle_num):
        particles[i] = ti.Vector([ti.random() * 3 - 1.5, ti.random() - 0.5])
 def random_point_in_unit_sphere(self):
     ret = ti.Vector.zero(ti.f32, n=self.dim)
     while True:
         for i in ti.static(range(self.dim)):
             ret[i] = ti.random(ti.f32) * 2 - 1
         if ret.norm_sqr() <= 1:
             break
     return ret
def initialize():
    for i in range(n_particles):
        x[i] = [ti.random() * 0.3 + 0.3, ti.random() * 0.3 + 0.25]
        # x[i] = [ti.random() * 0.6 + 0.2, ti.random() * 0.45 + 0.45 ]
        material[i] = 0  # 0: fluid, 1: jelly, 2: snow
        v[i] = ti.Matrix([0, 0])
        F[i] = ti.Matrix([[1, 0], [0, 1]])
        Jp[i] = 1
    for i in range(n_lines):  # add horizontal or vertical lines
        if i == 0:
            lines1[i] = [0.25, 0.15]
            lines2[i] = [0.25, 0.5]
        elif i == 1:
            lines1[i] = [0.25, 0.15]
            lines2[i] = [0.75, 0.15]
        elif i == 2:
            lines1[i] = [0.75, 0.15]
            lines2[i] = [0.75, 0.5]
Example #18
0
def Def(minval, maxval):
    '''
    Name: random_generator
    Category: texture
    Inputs: minval:f maxval:f
    Output: result:a
    '''

    return lambda pars: minval + ti.random() * (maxval - minval)
Example #19
0
def init():
    for i in range(particle_width):
        for j in range(particle_height):
            a[i, j] = ti.Vector([0.0,ti.random(type)-0.5])
            b[i, j] = a[i, j]
    normalize(a)
    B[None] = ti.Vector([0.0,magnetic_field])
    old_hamiltonian[None] = Hamiltonian(a)
    Magnitude[None]=M(a)
Example #20
0
def color(o, d):
    rst = ti.Vector([1.0, 1.0, 1.0])
    count = 0
    while True:
        if count > 10:
            break
        hit, p, n, index = hit_spheres(o, d, 0.001, 1e10)
        if hit:
            #命中点是下一条光线的起点
            o = p
            if spheres[index][4] <= 1.0:
                albedo = ti.Vector(
                    [spheres[index][5], spheres[index][6], spheres[index][7]])
                rst = rst * albedo
                #漫反射
                if spheres[index][4] == 0.0:
                    d = unit_vector(n + random_in_unit_sphere())
                #镜面反射
                elif spheres[index][4] == 1.0:
                    # d = unit_vector(reflect(d, n) + random_in_unit_sphere() * 0.03)
                    d = reflect(d, n)
                if n.dot(d) < 0:
                    rst = ti.Vector([0.0, 0.0, 0.0])
                    break
            #折射
            else:
                outward_n = n
                #折射率比值
                ni_over_nt = spheres[index][5]
                cosine = 0.0
                #从球体内部往外部
                if (d.dot(n)) > 0:
                    outward_n = -n
                    cosine = ni_over_nt * d.dot(n)
                #从球体外部到内部
                else:
                    ni_over_nt = 1.0 / ni_over_nt
                    cosine = -d.dot(n)
                succ, refracted = refract(d, outward_n, ni_over_nt)
                if succ:
                    #一定概率折射或者反射
                    reflect_prob = schlick(cosine, spheres[index][5])
                    if ti.random() < reflect_prob:
                        d = reflect(d, n)
                    else:
                        d = refracted
                #完全反射
                else:
                    d = reflect(d, n)
            count += 1
        else:
            t = 0.5 * (d[1] + 1.0)
            skycolor = (1.0 - t) * ti.Vector([1.0, 1.0, 1.0]) + t * ti.Vector(
                [0.5, 0.7, 1.0])
            rst = rst * skycolor
            break
    return rst
Example #21
0
def init_particles():
    for i in range(num_particles):
        delta = h * 0.8
        offs = ti.Vector([(boundary[0] - delta * num_particles_x) * 0.5,
                          boundary[1] * 0.02])
        positions[i] = ti.Vector([i % num_particles_x, i // num_particles_x
                                  ]) * delta + offs
        for c in ti.static(range(dim)):
            velocities[i][c] = (ti.random() - 0.5) * 4
    board_states[None] = ti.Vector([boundary[0] - epsilon, -0.0])
Example #22
0
def render():
    for u, v in color_buffer:
        aspect_ratio = res[0] / res[1]
        pos = camera_pos
        cur_iter = count_var[0]
        str_x, str_y = (cur_iter / stratify_res), (cur_iter % stratify_res)
        ray_dir = ti.Vector([
            (2 * fov * (u + (str_x + ti.random()) * inv_stratify) / res[1] -
             fov * aspect_ratio - 1e-5),
            (2 * fov * (v + (str_y + ti.random()) * inv_stratify) / res[1] -
             fov - 1e-5),
            -1.0,
        ])
        ray_dir = ray_dir.normalized()

        acc_color = ti.Vector([0.0, 0.0, 0.0])
        throughput = ti.Vector([1.0, 1.0, 1.0])

        depth = 0
        while depth < max_ray_depth:
            closest, hit_normal, hit_color, mat = intersect_scene(pos, ray_dir)
            if mat == mat_none:
                break

            hit_pos = pos + closest * ray_dir
            hit_light = (mat == mat_light)
            if hit_light:
                acc_color += throughput * light_color
                break
            elif mat == mat_lambertian:
                acc_color += throughput * sample_direct_light(
                    hit_pos, hit_normal, hit_color)

            depth += 1
            ray_dir, pdf = sample_ray_dir(ray_dir, hit_normal, hit_pos, mat)
            pos = hit_pos + 1e-4 * ray_dir
            if mat == mat_lambertian:
                throughput *= lambertian_brdf * hit_color * dot_or_zero(
                    hit_normal, ray_dir) / pdf
            else:
                throughput *= hit_color
        color_buffer[u, v] += acc_color
    count_var[0] = (count_var[0] + 1) % (stratify_res * stratify_res)
 def seed_from_voxels(self, material: ti.i32, color: ti.i32,
                      sample_density: ti.i32):
     for i, j, k in self.voxelizer.voxels:
         inside = 1
         for d in ti.static(range(3)):
             inside = inside and -self.grid_size // 2 + self.padding <= i and i < self.grid_size // 2 - self.padding
         if inside and self.voxelizer.voxels[i, j, k] > 0:
             s = sample_density / self.voxelizer_super_sample**self.dim
             for l in range(sample_density + 1):
                 if ti.random() + l < s:
                     x = ti.Vector([
                         ti.random() + i,
                         ti.random() + j,
                         ti.random() + k
                     ]) * (self.dx / self.voxelizer_super_sample
                           ) + self.source_bound[0]
                     p = ti.atomic_add(self.n_particles[None], 1)
                     self.seed_particle(p, x, material, color,
                                        self.source_velocity[None])
 def seed(self, new_particles: ti.i32, new_material: ti.i32, color: ti.i32):
     for i in range(self.n_particles[None],
                    self.n_particles[None] + new_particles):
         self.material[i] = new_material
         x = ti.Vector.zero(ti.f32, self.dim)
         for k in ti.static(range(self.dim)):
             x[k] = self.source_bound[0][k] + ti.random(
             ) * self.source_bound[1][k]
         self.seed_particle(i, x, new_material, color,
                            self.source_velocity[None])
Example #25
0
 def seed(self, num_original_particles: ti.i32, new_particles: ti.i32,
          new_material: ti.i32):
     for i in range(num_original_particles,
                    num_original_particles + new_particles):
         self.material[i] = new_material
         for k in ti.static(range(self.dim)):
             self.x[i][k] = self.source_bound[0][k] + ti.random(
             ) * self.source_bound[1][k]
         self.v[i] = ti.Vector.zero(ti.f32, self.dim)
         self.F[i] = ti.Matrix.identity(ti.f32, self.dim)
         self.Jp[i] = 1
Example #26
0
def apply_force(velocities:ti.template(), colors:ti.template(), pre_mouse_pos:ti.ext_arr(), cur_mouse_pos:ti.ext_arr()):

	p = ti.Vector([cur_mouse_pos[0], cur_mouse_pos[1]])
	pre_p = ti.Vector([pre_mouse_pos[0], pre_mouse_pos[1]])

	dp = p - pre_p
	dp = dp / max(1e-5, dp.norm())

	color = (ti.Vector([ti.random(), ti.random(), ti.random()]) * 0.7 + ti.Vector([0.1, 0.1, 0.1]) * 0.3)

	for i, j in velocities:


		d2 = (ti.Vector([(i+stagger.x)*dx, (j+stagger.y)*dx]) - p).norm_sqr()

		radius = 0.0001
		velocities[i, j] = velocities[i, j] + dp * dt * ti.exp(-d2/radius) * 40


		if dp.norm() > 0.5:
			colors[i, j] = colors[i, j] + ti.exp(-d2 * (4 / (1 / 15)**2)) * color
def init():
    vortex[0] = ti.Vector([0, 1])
    vortex[1] = ti.Vector([0, -1])
    vortex[2] = ti.Vector([0, 0.3])
    vortex[3] = ti.Vector([0, -0.3])
    vortex[4] = ti.Vector([0, 0.65])
    vortex[5] = ti.Vector([0, -0.65])

    sign[0] = 1
    sign[1] = -1
    sign[2] = 1
    sign[3] = -1
    sign[4] = 1
    sign[5] = -1

    for i in range(particle_num):
        x = ti.random()
        y = ti.random()
        particles[i] = ti.Vector([x * 3 - 1.5, y - 0.5])
        # colors[i] = ti.Vector([x, y, y])
        colors[i] = ti.Vector([x + 0.3, y + 0.3, 0.0])
Example #28
0
 def init_markers(self):
     self.total_mk[None] = 0
     for I in ti.grouped(self.cell_type):
         if self.cell_type[I] == utils.FLUID:
             for offset in ti.static(
                     ti.grouped(ti.ndrange(*((0, 2), ) * self.dim))):
                 num = ti.atomic_add(self.total_mk[None], 1)
                 self.p_x[num] = (
                     I +
                     (offset +
                      [ti.random()
                       for _ in ti.static(range(self.dim))]) / 2) * self.dx
Example #29
0
def add_random_particles(angular_velocity: ti.f32):
    num = ti.static(1)
    particle_id = alloc_particle()
    if ti.static(kDim == 2):
        particle_pos[particle_id] = rand_disk_2d() * 0.2 + 0.5
        velocity = (particle_pos[particle_id] - 0.5) * angular_velocity * 250
        particle_vel[particle_id] = ti.Vector([-velocity.y, velocity.x])
    else:
        particle_pos[particle_id] = rand_unit_3d() * 0.2 + 0.5
        velocity = (ti.Vector(
            [particle_pos[particle_id].x, particle_pos[particle_id].y]) -
                    0.5) * angular_velocity * 180
        particle_vel[particle_id] = ti.Vector([-velocity.y, velocity.x, 0.0])
    particle_mass[particle_id] = 1.5 * ti.random()
Example #30
0
def sample_brdf(normal):
    # cosine hemisphere sampling
    # Uniformly sample on a disk using concentric sampling(r, theta)
    # https://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/2D_Sampling_with_Multidimensional_Transformations#CosineSampleHemisphere
    r, theta = 0.0, 0.0
    sx = ti.random() * 2.0 - 1.0
    sy = ti.random() * 2.0 - 1.0
    if sx != 0 or sy != 0:
        if abs(sx) > abs(sy):
            r = sx
            theta = np.pi / 4 * (sy / sx)
        else:
            r = sy
            theta = np.pi / 4 * (2 - sx / sy)
    # Apply Malley's method to project disk to hemisphere
    u = ti.Vector([1.0, 0.0, 0.0])
    if abs(normal[1]) < 1 - eps:
        u = normal.cross(ti.Vector([0.0, 1.0, 0.0]))
    v = normal.cross(u)
    costt, sintt = ti.cos(theta), ti.sin(theta)
    xy = (u * costt + v * sintt) * r
    zlen = ti.sqrt(ti.max(0.0, 1.0 - xy.dot(xy)))
    return xy + zlen * normal