void Balloon::render() { glColor3f(0.5,0.5,0.5); for(int i=0; i<m_positions.rows(); i++) { glPushMatrix(); { glTranslated(m_positions(i,0), m_positions(i,1), m_positions(i,2)); glutSolidSphere(m_radius, 50, 50); } glPopMatrix(); glPushMatrix(); { if(false) { double nl = 5; glLineWidth(0.01); glColor3d(0.0, 1.0, 0.0); glBegin(GL_LINES); glVertex3d(m_positions(i,0), m_positions(i,1), m_positions(i,2)); glVertex3d(m_positions(i,0) + m_normals(i,0) * nl, m_positions(i,1) + m_normals(i,1) * nl, m_positions(i,2) + m_normals(i,2) * nl); glEnd(); } } glPopMatrix(); } for(int i=0; i<m_faces.rows(); i++) { glPushMatrix(); { if(m_faceactive(i) == 1) { glLineWidth(0.01); glColor4d(1.0, 0.0, 0.0, 1.0); if(renderTriangle) { glBegin(GL_TRIANGLES); } else{ glBegin(GL_LINE_LOOP); } glVertex3d(m_positions(m_faces(i,0),0), m_positions(m_faces(i,0),1), m_positions(m_faces(i,0),2)); glVertex3d(m_positions(m_faces(i,1),0), m_positions(m_faces(i,1),1), m_positions(m_faces(i,1),2)); glVertex3d(m_positions(m_faces(i,2),0), m_positions(m_faces(i,2),1), m_positions(m_faces(i,2),2)); glEnd(); } } glPopMatrix(); } }
void Balloon::update() { // update position & speed Eigen::MatrixXd X_n(m_positions.rows(), m_positions.cols()); Eigen::MatrixXd V_n(m_speeds.rows(), m_speeds.cols()); for(int i=0; i<m_positions.rows(); i++) { Eigen::Vector3d v_n; Eigen::Vector3d x_p = m_positions.row(i); Eigen::Vector3d v_p = m_speeds.row(i); Eigen::Vector3d f_p = m_forces.row(i); if(true) { v_n = ((m_mass-m_step*(-c*m_adjacency_list[i].size()))*v_p +(f_p-d*v_p)*m_step)/(m_mass-m_step*(-c*m_adjacency_list[i].size())-m_step*m_step*(-k*m_adjacency_list[i].size())); } { v_n = v_p + m_step / m_mass * f_p; } X_n.row(i) = x_p + m_step * v_n; V_n.row(i) = v_n; } m_positions = X_n; m_speeds = V_n; m_forces = Eigen::MatrixXd::Zero(m_positions.rows(), m_positions.cols()); if(!isActive) { // m_air_pressure /= 5.0; for(int i=0; i<m_positions.rows(); i++) { // m_forces.row(i) += m_mass * g * Eigen::Vector3d(0,0,-1); } for(int i=0; i<m_faces.rows(); i++) { if(m_faceactive(i) == 0) { for(int j=0; j<3; j++) { std::vector<int> faceids = m_vertextoface[m_faces(i,j)]; for(int k=0; k<faceids.size(); k++) { m_threshold_ratio(m_facetoedge(faceids[k],0)) /= 2.0; m_threshold_ratio(m_facetoedge(faceids[k],1)) /= 2.0; m_threshold_ratio(m_facetoedge(faceids[k],2)) /= 2.0; } } } } } // check activity for(int i=0; i<m_edges.rows(); i++) { if(m_edgeactive(i) == 1) { Eigen::Vector3d l = m_positions.row(m_edges(i,0)) - m_positions.row(m_edges(i,1)); if(l.norm() > m_edgelength(i)*threshold_ratio) { m_edgeactive(i) = 0; m_faceactive(m_edgetoface(i,0)) = 0; m_faceactive(m_edgetoface(i,1)) = 0; isActive = false; std::cout << "inactive" << std::endl; } } } // calc forces for(int i=0; i<m_edges.rows(); i++) { if(m_edgeactive(i) == 1) { Eigen::Vector3d f_n = Eigen::Vector3d(0,0,0); Eigen::Vector3d x_1 = m_positions.row(m_edges(i,0)); Eigen::Vector3d x_2 = m_positions.row(m_edges(i,1)); Eigen::Vector3d v_1 = m_speeds.row(m_edges(i,0)); Eigen::Vector3d v_2 = m_speeds.row(m_edges(i,1)); f_n -= k*((x_1 - x_2).norm() - m_edgelength(i))*(x_1 - x_2).normalized(); f_n -= c*((v_1 - v_2).dot((x_1 - x_2).normalized()))*(x_1 - x_2).normalized(); m_forces.row(m_edges(i,0)) += f_n; m_forces.row(m_edges(i,1)) += -f_n; } } computeNormals(); m_forces += m_air_pressure * m_normals; /* for(int i=0; i<m_positions.rows(); i++) { Eigen::Vector3d f_n = Eigen::Vector3d(0,0,0); Eigen::Vector3d x_p = m_positions.row(i); Eigen::Vector3d v_p = m_speeds.row(i); // f_n += m_mass * g * Eigen::Vector3d(0,0,-1); f_n += m_air_pressure * m_normals.row(i); for(int j=0; j<m_adjacency_list[i].size(); j++) { Eigen::Vector3d x_j = m_positions.row(m_adjacency_list[i][j]); Eigen::Vector3d v_j = m_speeds.row(m_adjacency_list[i][j]); f_n -= k*((x_p - x_j).norm() - m_length_list[i][j])*(x_p - x_j).normalized(); f_n -= c*((v_p - v_j).dot((x_p - x_j).normalized()))*(x_p - x_j).normalized(); } Eigen::Vector3d v_n; if(true) { v_n = ((m_mass-m_step*(-c*m_adjacency_list[i].size()))*v_p +(f_n-d*v_p)*m_step)/(m_mass-m_step*(-c*m_adjacency_list[i].size())-m_step*m_step*(-k*m_adjacency_list[i].size())); } { v_n = v_p + m_step / m_mass * f_n; } X_n.row(i) = x_p + m_step * v_n; V_n.row(i) = v_n; } */ // m_positions = X_n; // m_speeds = V_n; }
void Balloon::update() { // update position & speed Eigen::MatrixXd X_n(m_positions.rows(), m_positions.cols()); Eigen::MatrixXd V_n(m_speeds.rows(), m_speeds.cols()); for(int i=0; i<m_positions.rows(); i++) { Eigen::Vector3d v_n; Eigen::Vector3d x_p = m_positions.row(i); Eigen::Vector3d v_p = m_speeds.row(i); Eigen::Vector3d f_p = m_forces.row(i); if(true) { // v_n = ((m_mass-m_step*(-c*m_adjacency_list[i].size()))*v_p +(f_p-c*v_p)*m_step)/(m_mass-m_step*(-c*m_adjacency_list[i].size())-m_step*m_step*(-k*m_adjacency_list[i].size())); // v_n = ((m_mass-m_step*(-c))*v_p + f_p)/(m_mass-m_step*(-c)-m_step*m_step*(-k)); v_n = ((m_mass-m_step*(-d))*v_p + f_p-d*v_p)/(m_mass-m_step*(-d)-m_step*m_step*(-k)); // v_n = ((m_mass-m_step*(-d))*v_p +(f_p-d*v_p)*m_step)/(m_mass-m_step*(-d)-m_step*m_step*(-k*m_adjacency_list[i].size())); } { v_n = v_p + m_step / m_mass * f_p; } X_n.row(i) = x_p + m_step * v_n; V_n.row(i) = v_n; } m_positions = X_n; m_speeds = V_n; checkfloor(); calcAveRadius(); m_forces = Eigen::MatrixXd::Zero(m_positions.rows(), m_positions.cols()); if(!isActive) { // m_air_pressure /= 5.0; for(int i=0; i<m_positions.rows(); i++) { m_forces.row(i) += m_mass * g * Eigen::Vector3d(0,0,-1); } for(int i=0; i<m_faces.rows(); i++) { if(m_faceactive(i) == 0) { for(int j=0; j<3; j++) { std::vector<int> faceids = m_vertextoface[m_faces(i,j)]; for(int k=0; k<faceids.size(); k++) { m_threshold_ratio(m_facetoedge(faceids[k],0)) /= 2.0; m_threshold_ratio(m_facetoedge(faceids[k],1)) /= 2.0; m_threshold_ratio(m_facetoedge(faceids[k],2)) /= 2.0; } } } } } // check activity for(int i=0; i<m_edges.rows(); i++) { if(m_edgeactive(i) == 1) { Eigen::Vector3d l = m_positions.row(m_edges(i,0)) - m_positions.row(m_edges(i,1)); if(l.norm() > m_edgelength(i)*threshold_ratio) { m_edgeactive(i) = 0; m_faceactive(m_edgetoface(i,0)) = 0; m_faceactive(m_edgetoface(i,1)) = 0; isActive = false; } } } // calc forces for(int i=0; i<m_edges.rows(); i++) { if(m_edgeactive(i) == 1) { Eigen::Vector3d f_n = Eigen::Vector3d(0,0,0); Eigen::Vector3d x_1 = m_positions.row(m_edges(i,0)); Eigen::Vector3d x_2 = m_positions.row(m_edges(i,1)); Eigen::Vector3d v_1 = m_speeds.row(m_edges(i,0)); Eigen::Vector3d v_2 = m_speeds.row(m_edges(i,1)); if((x_1-x_2).norm()>m_edgelength(i)){ f_n -= k*((x_1 - x_2).norm() - m_edgelength(i))*(x_1 - x_2).normalized(); } else{ f_n -= 1.0*k*((x_1 - x_2).norm() - m_edgelength(i))*(x_1 - x_2).normalized(); } f_n -= c*((v_1 - v_2).dot((x_1 - x_2).normalized()))*(x_1 - x_2).normalized(); m_forces.row(m_edges(i,0)) += f_n; m_forces.row(m_edges(i,1)) += -f_n; } } computeNormals(); if(useWater) { m_forces += m_air_pressure * m_normals / (double)m_average_radius; // std::cout << "p_force" << m_air_pressure * (double)m_average_radius*(double)m_average_radius*4.0*M_PI/m_num_point<< std::endl; } { m_forces += m_air_pressure * m_normals / (double)m_average_radius; // std::cout << "p_force" << m_air_pressure / (double)m_average_radius << std::endl; } }
size_t DuplicatedVertexRemoval::run(Float tol) { const size_t dim = m_vertices.cols(); HashGrid::Ptr grid = HashGrid::create(tol, dim); const size_t num_vertices = m_vertices.rows(); const size_t num_faces = m_faces.rows(); const size_t vertex_per_face = m_faces.cols(); m_index_map.resize(num_vertices); std::vector<size_t> source_index; size_t count = 0; size_t num_duplications = 0; for (size_t i=0; i<num_vertices; i++) { int curr_importance_level = m_importance_level[i]; if (curr_importance_level < 0) { m_index_map[i] = count; source_index.push_back(i); count++; continue; } const VectorF& v = m_vertices.row(i); VectorI candidates = grid->get_items_near_point(v); const size_t num_candidates = candidates.size(); if (num_candidates > 0) { VectorF dists(num_candidates); for (size_t j=0; j<num_candidates; j++) { dists[j] = (m_vertices.row(candidates[j]) - v.transpose()).norm(); } size_t min_idx; Float min_dist = dists.minCoeff(&min_idx); if (min_dist < tol) { size_t best_match_idx = candidates[min_idx]; size_t output_idx = m_index_map[best_match_idx]; m_index_map[i] = output_idx; int matched_importance_level = m_importance_level[source_index[output_idx]]; if (curr_importance_level > matched_importance_level) { source_index[output_idx] = i; } num_duplications++; continue; } } // No match, add this vertex in the book. grid->insert(i, v); m_index_map[i] = count; source_index.push_back(i); count++; } assert(source_index.size() == count); MatrixFr vertices(count, dim); for (size_t i=0; i<count; i++) { assert(m_index_map[source_index[i]] == i); vertices.row(i) = m_vertices.row(source_index[i]); } m_vertices = vertices; for (size_t i=0; i<num_faces; i++) { for (size_t j=0; j<vertex_per_face; j++) { size_t v_index = m_faces(i,j); m_faces(i,j) = m_index_map[v_index]; } } return num_duplications; }