Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
hs = halfsize[i]
for k in ti.static(range(4)):
f = friction[None]
# the corner for collision detection
offset_scale = ti.Vector([k % 2 * 2 - 1, k // 2 % 2 * 2 - 1])
corner_x, corner_v, rela_pos = to_world(t, i, offset_scale * hs)
corner_v = corner_v + dt * gravity * ti.Vector([0.0, 1.0])
# Apply impulse so that there's no sinking
normal = ti.Vector([0.0, 1.0])
tao = ti.Vector([1.0, 0.0])
rn = cross(rela_pos, normal)
rt = cross(rela_pos, tao)
impulse_contribution = inverse_mass[i] + ti.sqr(rn) * \
inverse_inertia[i]
timpulse_contribution = inverse_mass[i] + ti.sqr(rt) * \
inverse_inertia[i]
rela_v_ground = normal.dot(corner_v)
impulse = 0.0
timpulse = 0.0
if rela_v_ground < 0 and corner_x[1] < ground_height:
impulse = -(1 + elasticity) * rela_v_ground / impulse_contribution
if impulse > 0:
# friction
timpulse = -corner_v.dot(tao) / timpulse_contribution
timpulse = ti.min(f * impulse, ti.max(-f * impulse, timpulse))
if corner_x[1] < ground_height:
def p2g(f: ti.i32):
for p in range(0, n_particles):
base = ti.cast(x[f, p] * inv_dx - 0.5, ti.i32)
fx = x[f, p] * inv_dx - ti.cast(base, ti.i32)
w = [0.5 * ti.sqr(1.5 - fx), 0.75 - ti.sqr(fx - 1), 0.5 * ti.sqr(fx - 0.5)]
new_F = (ti.Matrix.diag(dim=2, val=1) + dt * C[f, p]) @ F[f, p]
F[f + 1, p] = new_F
J = ti.determinant(new_F)
r, s = ti.polar_decompose(new_F)
cauchy = 2 * mu * (new_F - r) @ ti.transposed(new_F) + \
ti.Matrix.diag(2, la * (J - 1) * J)
stress = -(dt * p_vol * 4 * inv_dx * inv_dx) * cauchy
affine = stress + p_mass * C[f, p]
for i in ti.static(range(3)):
for j in ti.static(range(3)):
offset = ti.Vector([i, j])
dpos = (ti.cast(ti.Vector([i, j]), real) - fx) * dx
weight = w[i](0) * w[j](1)
grid_v_in[base + offset] += weight * (p_mass * v[f, p] + affine @ dpos)
grid_m_in[base + offset] += weight * p_mass
def compute_loss(t: ti.i32):
for i in range(n_grid):
for j in range(n_grid):
ti.atomic_add(loss, dx * dx * ti.sqr(target[i, j] - p[t, i, j]))
def p2g():
for p in x:
base = ti.cast(x[p] * inv_dx - 0.5, ti.i32)
fx = x[p] * inv_dx - ti.cast(base, ti.f32)
w = [0.5 * ti.sqr(1.5 - fx), 0.75 - ti.sqr(fx - 1), 0.5 * ti.sqr(fx - 0.5)]
affine = p_mass * C[p]
for i in ti.static(range(3)):
for j in ti.static(range(3)):
offset = ti.Vector([i, j])
dpos = (ti.cast(ti.Vector([i, j]), ti.f32) - fx) * dx
weight = w[i](0) * w[j](1)
grid_v[base + offset].atomic_add(
weight * (p_mass * v[p] - x.grad[p] + affine @ dpos))
grid_m[base + offset].atomic_add(weight * p_mass)
def compute_loss(view_id: ti.i32):
for i in range(res):
for j in range(res):
ti.atomic_add(
loss,
ti.sqr(images[view_id, i, j] - target_images[view_id, i, j]) *
(1.0 / (res * res)))
def p2g(f: ti.i32):
for p in range(0, n_particles):
base = ti.cast(x[f, p] * inv_dx - 0.5, ti.i32)
fx = x[f, p] * inv_dx - ti.cast(base, ti.i32)
w = [0.5 * ti.sqr(1.5 - fx), 0.75 - ti.sqr(fx - 1), 0.5 * ti.sqr(fx - 0.5)]
new_F = (ti.Matrix.diag(dim=2, val=1) + dt * C[f, p]) @ F[f, p]
F[f + 1, p] = new_F
J = ti.determinant(new_F)
r, s = ti.polar_decompose(new_F)
cauchy = 2 * mu * (new_F - r) @ ti.transposed(new_F) + \
ti.Matrix.diag(2, la * (J - 1) * J)
stress = -(dt * p_vol * 4 * inv_dx * inv_dx) * cauchy
affine = stress + p_mass * C[f, p]
for i in ti.static(range(3)):
for j in ti.static(range(3)):
offset = ti.Vector([i, j])
dpos = (ti.cast(ti.Vector([i, j]), real) - fx) * dx
weight = w[i](0) * w[j](1)
grid_v_in[base + offset].atomic_add(
weight * (p_mass * v[f, p] + affine @ dpos))
grid_m_in[base + offset].atomic_add(weight * p_mass)
def p2g(f: ti.i32):
for p in range(0, n_particles):
base = ti.cast(x[f, p] * inv_dx - 0.5, ti.i32)
fx = x[f, p] * inv_dx - ti.cast(base, ti.i32)
w = [0.5 * ti.sqr(1.5 - fx), 0.75 - ti.sqr(fx - 1), 0.5 * ti.sqr(fx - 0.5)]
new_F = (ti.Matrix.diag(dim=dim, val=1) + dt * C[f, p]) @ F[f, p]
J = ti.determinant(new_F)
if particle_type[p] == 0: # fluid
sqrtJ = ti.sqrt(J)
# TODO: need pow(x, 1/3)
new_F = ti.Matrix([[sqrtJ, 0, 0], [0, sqrtJ, 0], [0, 0, 1]])
F[f + 1, p] = new_F
# r, s = ti.polar_decompose(new_F)
act_id = actuator_id[p]
act = actuation[f, ti.max(0, act_id)] * act_strength
if act_id == -1:
act = 0.0
# ti.print(act)
def copy(img: np.ndarray):
for i in range(res[0]):
for j in range(res[1]):
u = 1.0 * i / res[0]
v = 1.0 * j / res[1]
darken = 1.0 - vignette_strength * ti.max((ti.sqrt(
ti.sqr(u - vignette_center[0]) + ti.sqr(v - vignette_center[1])) -
vignette_radius), 0)
coord = ((res[1] - 1 - j) * res[0] + i) * 3
for c in ti.static(range(3)):
img[coord + c] = color_buffer[i, j][2 - c] * darken