Beispiel #1
0
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();
    }
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}