def draw_object(self, model): if self.DRAW_LINES: glLineWidth(1) glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ) glBegin(GL_TRIANGLES) for face in model.faces: for v_id in face.vertex_ids(): vert = model.rendering_verts[v_id] glColor3f(1,0,0) glVertex3f(vert[0], vert[1], vert[2]) glEnd() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glBegin(GL_TRIANGLES) for face in model.faces: for v_id in face.vertex_ids(): vert = model.rendering_verts[v_id] uv = model.uvs[v_id] glColor3f(1,1,1) glTexCoord2f(uv[0], uv[1]) glVertex3f(vert[0], vert[1], vert[2]) glEnd() glBegin(GL_LINES) glVertex3f(0,-300,0) vert = model.verts[0] glVertex3f(vert[0], vert[1], vert[2]) glEnd()
def simulate_triangle(self): forces = self.wind_forces(self.count) forces[:, 1] = -1 acc = (self.stepsize * self.stepsize) * linalg.inv(self.mass_matrix).dot(forces) dist = self.velocities * self.stepsize s_n = self.rendering_verts + dist + acc q_n_1 = np.copy(s_n) b_array = np.zeros((self.n + len(self.fixed_points), 3)) M = self.mass_matrix / (self.stepsize * self.stepsize) for _ in range(1): b_array[:self.n] = M.dot(s_n) for face in self.faces: f_verts = face.vertex_ids() for i in range(3): v1 = f_verts[i] v2 = f_verts[(i + 1) % 3] T = self.potential_for_triangle(face, q_n_1, v2) edge = self.verts[v2] - self.verts[v1] g = T.dot(edge) b_array[v1] = b_array[v1] - g b_array[v2] = b_array[v2] + g # Assign fixed points for con_i in range(len(self.fixed_points)): con = self.fixed_points[con_i] b_array[-(con_i + 1)] = self.verts[con.vert_a] q_n_1 = np.linalg.solve(self.global_matrix, b_array) q_n_1 = q_n_1[:-len(self.fixed_points), :] # Don't grab the unwanted fixed points self.velocities = ((q_n_1 - self.rendering_verts) * 0.9) / self.stepsize self.rendering_verts = q_n_1
def calculate_triangle_global_matrix(self): fixed_point_num = len(self.fixed_points) M = np.zeros((self.n + fixed_point_num, self.n + fixed_point_num)) M[:self.n, :self.n] = self.mass_matrix M /= (self.stepsize * self.stepsize) weights = np.zeros((self.n + fixed_point_num, self.n + fixed_point_num)) weight_sum = np.zeros((self.n + fixed_point_num, self.n + fixed_point_num)) for face in self.faces: verts = face.vertex_ids() for k in range(3): v_1 = verts[k] v_2 = verts[(k + 1) % 3] weights[v_1, v_2] += 1 weights[v_2, v_1] += 1 weight_sum[v_1, v_1] += 1 weight_sum[v_2, v_2] += 1 x = weight_sum - weights for i in range(fixed_point_num): con = self.fixed_points[i] x[con.vert_a, -(i + 1)] = 1 x[-(i + 1), con.vert_a] = 1 M[-(i + 1), -(i + 1)] = 0 return x + M
def __init__(self, verts, faces, neighbours=[], uvs = [], constraints=[], flag_type=default_flag_type): self.flag_type = flag_type self.n = len(verts) self.verts = verts self.rendering_verts = np.copy(verts) self.faces = faces self.neighbours = neighbours for i in range(len(neighbours)): neighbours[i] = list(set(neighbours[i])) self.verts_to_tri = [] for i in range(self.n): in_faces = [] for face in self.faces: if i in face.vertex_ids(): in_faces.append(face) self.verts_to_tri.append(in_faces) self.uvs = uvs self.stepsize = 0.3 self.velocities = np.zeros((self.n, 3)) self.mass_matrix = np.identity(self.n) self.constraints = constraints self.fixed_points = [] for con in self.constraints: if con.type() == "FIXED": self.fixed_points.append(con) if self.flag_type == "imp_tri": self.mass_matrix /= (len(self.faces)) self.global_matrix = self.calculate_triangle_global_matrix() self.count = 0 self.wind_magnitude = 5
def simulate_triangle_explicit(self): forces = self.wind_forces(self.count) forces[:, 1] = -10 s_n = self.rendering_verts for face in self.faces: res_tri_center = face.center_of_triangle(self.verts) def_tri_center = face.center_of_triangle(s_n) for vert_id in face.vertex_ids(): T = self.potential_for_triangle(face, s_n, vert_id) x = self.verts[vert_id] - res_tri_center # bring to origin x = T.dot(x) # apply rotation x = x + def_tri_center # reset to original spot y = (x - s_n[vert_id]) forces[vert_id] = forces[vert_id] + y acc = (self.stepsize * self.stepsize) * linalg.inv(self.mass_matrix).dot(forces) dist = self.velocities * self.stepsize s_n = self.rendering_verts + dist + acc for con_i in range(len(self.fixed_points)): con = self.fixed_points[con_i] s_n[con.vert_a] = self.verts[con.vert_a] self.rendering_verts = s_n