TEST_F(CollisionDetectorTest, projectile_gameobject_no_collision) {
    CollisionDetector detector;
    NiceMock<MockGameObject> projectile;
    NiceMock<MockHitbox> proj_hitbox;
    NiceMock<MockGameObject> gameobj;
    NiceMock<MockHitbox> gameobj_hitbox;
    ON_CALL(projectile, hitbox()).WillByDefault(ReturnRef(proj_hitbox));
    ON_CALL(proj_hitbox, is_overlapping(Ref(gameobj_hitbox))).WillByDefault(Return(false));
    ON_CALL(gameobj, hitbox()).WillByDefault(ReturnRef(gameobj_hitbox));
    ON_CALL(gameobj_hitbox, is_overlapping(Ref(proj_hitbox))).WillByDefault(Return(false));
    EXPECT_CALL(projectile, notify_collision(Ref(gameobj))).Times(0);
    EXPECT_CALL(gameobj, notify_collision(Ref(projectile))).Times(0);
    detector.add_projectile(Team::FRIENDLY, projectile);
    detector.add_game_object(Team::ENEMY, gameobj);
    detector.check_collisions();
}
TEST_F(CollisionDetectorTest, projectile_projectile) {
    CollisionDetector detector;
    NiceMock<MockGameObject> proj_1;
    NiceMock<MockHitbox> proj_1_hitbox;
    NiceMock<MockGameObject> proj_2;
    NiceMock<MockHitbox> proj_2_hitbox;
    ON_CALL(proj_1, hitbox()).WillByDefault(ReturnRef(proj_1_hitbox));
    ON_CALL(proj_1_hitbox, is_overlapping(Ref(proj_2_hitbox))).WillByDefault(Return(true));
    ON_CALL(proj_2, hitbox()).WillByDefault(ReturnRef(proj_2_hitbox));
    ON_CALL(proj_2_hitbox, is_overlapping(Ref(proj_1_hitbox))).WillByDefault(Return(true));
    EXPECT_CALL(proj_1, notify_collision(Ref(proj_2))).Times(0);
    EXPECT_CALL(proj_2, notify_collision(Ref(proj_1))).Times(0);
    detector.add_projectile(Team::FRIENDLY, proj_1);
    detector.add_projectile(Team::ENEMY, proj_2);
    detector.check_collisions();
}
TEST_F(CollisionDetectorTest, gameobject_gameobject_no_collision) {
    CollisionDetector detector;
    NiceMock<MockGameObject> gameobj_1;
    NiceMock<MockHitbox> hitbox_1;
    NiceMock<MockGameObject> gameobj_2;
    NiceMock<MockHitbox> hitbox_2;
    ON_CALL(gameobj_1, hitbox()).WillByDefault(ReturnRef(hitbox_1));
    ON_CALL(hitbox_1, is_overlapping(Ref(hitbox_2))).WillByDefault(Return(false));
    ON_CALL(gameobj_2, hitbox()).WillByDefault(ReturnRef(hitbox_2));
    ON_CALL(hitbox_2, is_overlapping(Ref(hitbox_1))).WillByDefault(Return(false));
    EXPECT_CALL(gameobj_1, notify_collision(Ref(gameobj_2))).Times(0);
    EXPECT_CALL(gameobj_2, notify_collision(Ref(gameobj_1))).Times(0);
    detector.add_game_object(Team::FRIENDLY, gameobj_1);
    detector.add_game_object(Team::ENEMY, gameobj_2);
    detector.check_collisions();
}
예제 #4
0
int main(int argc, char** argv) {
  // Check arguments
  if (argc < 5) {
    std::cerr << "Usage: " << argv[0] << " NODES_FILE TETS_FILE\n";
    exit(1);
  }

  // Construct the first mesh
  MeshType mesh;
  //construct the second mesh
  MeshType mesh2;

  std::vector<typename MeshType::node_type> mesh_node;
  // Read all Points and add them to the Mesh
  std::ifstream nodes_file(argv[1]);
  Point p;
  while (CS207::getline_parsed(nodes_file, p)) {
    mesh_node.push_back(mesh.add_node(p));
  }

  // Read all mesh triangles and add them to the Mesh
  std::ifstream tris_file(argv[2]);
  std::array<int,3> t;
  while (CS207::getline_parsed(tris_file, t)) {
    mesh.add_triangle(mesh_node[t[0]], mesh_node[t[1]], mesh_node[t[2]]);
  }

  std::vector<typename MeshType::node_type> mesh_node2;
  // Read all Points and add them to the Mesh
  std::ifstream nodes_file2(argv[3]);
  while (CS207::getline_parsed(nodes_file2, p)) {
    mesh_node2.push_back(mesh2.add_node(p));
  }

  // Read all mesh triangles and add them to the Mesh
  std::ifstream tris_file2(argv[4]);
  while (CS207::getline_parsed(tris_file2, t)) {
    mesh2.add_triangle(mesh_node2[t[0]], mesh_node2[t[1]], mesh_node2[t[2]]);
  }
  
  //move the second mesh to the specified position
  for(auto it = mesh2.node_begin();it!=mesh2.node_end();++it){
    (*it).position().elem[1] +=4 ;
    (*it).position().elem[2] +=4 ;
  }

  // Print out the stats
  std::cout << mesh.num_nodes() << " "
            << mesh.num_edges() << " "
            << mesh.num_triangles() << std::endl;
  std::cout << mesh2.num_nodes() << " "
            << mesh2.num_edges() << " "
            << mesh2.num_triangles() << std::endl;



  //set the mass and velocity of each Node for the first mesh
  for (auto it = mesh.node_begin(); it != mesh.node_end(); ++it){
    (*it).value().mass = float(1)/mesh.num_nodes();
    (*it).value().velocity = Point(0, 10, 10);
  }
  //set the mass and velocity of each Node for the second mesh
  for (auto it = mesh2.node_begin(); it != mesh2.node_end(); ++it){
    (*it).value().mass = float(1)/mesh.num_nodes();
    (*it).value().velocity = Point(0, -10, -10);
  }

  //set K and L for each edge
  for (auto it = mesh.node_begin(); it != mesh.node_end(); ++it)
  {
    for (auto j = (*it).edge_begin(); j != (*it).edge_end(); ++j){
       (*j).value().L = (*j).length();
       (*j).value().K = 16000;
    }
  }

  for (auto it = mesh2.node_begin(); it != mesh2.node_end(); ++it)
  {
    for (auto j = (*it).edge_begin(); j != (*it).edge_end(); ++j){
       (*j).value().L = (*j).length();
       (*j).value().K = 16000;
    }
  }


  // Launch the SDLViewer
  CS207::SDLViewer viewer;
  auto node_map = viewer.empty_node_map(mesh);
  viewer.launch();

  viewer.add_nodes(mesh.node_begin(), mesh.node_end(), node_map);
  viewer.add_edges(mesh.edge_begin(), mesh.edge_end(), node_map);
  viewer.add_nodes(mesh2.node_begin(), mesh2.node_end(), node_map);
  viewer.add_edges(mesh2.edge_begin(), mesh2.edge_end(), node_map);

  viewer.center_view();
  
  //Begin the mass-spring simulation
  double dt = 0.0002;
  double t_start = 0.0;
  double t_end   = 10.0;
   
  //three color parameter
  int color1 = 1; 
  int color2 = 1; 
  int color3 = 1; 
  
  //Create listener
  Pause_listener* pause = new Pause_listener(dt); 
  Speed_listener* speed = new Speed_listener(dt, dt); 
  XYZ_listener<MeshType>* xyz = new XYZ_listener<MeshType>(&mesh);
  Color_listener* col = new Color_listener(&color1, &color2, &color3);
  
  //add listener
  viewer.add_listener(pause);
  viewer.add_listener(speed);
  viewer.add_listener(xyz);
  viewer.add_listener(col);

  //Initialize forces
  WindForce wind_force(Point(0,100,200));
  PressureForce<typename MeshType::node_type, MeshType> pressure_force(1, 2500, &mesh);
  DampingForce damp_force(float(1)/mesh.num_nodes());
  //auto force = make_combined_force(MassSpringForce(), GravityForce(), make_combined_force(pressure_force, damp_force, wind_force));
  auto force = make_combined_force(MassSpringForce(), make_combined_force(pressure_force, damp_force, wind_force));
  
  //Initialize constriants
  auto constraint = PlaneConstraint<MeshType>(-4);

  //simulation processing   
  for (double t = t_start; t < t_end; t += dt) {
    constraint(mesh, 0);
    constraint(mesh2, 0);
    //define a collision constrain
    auto collision_constrain = CollisionConstraint<MeshType>();
    //add the forces to the meshs at each dt
    symp_euler_step(mesh, t, dt, force);
    symp_euler_step(mesh2, t, dt, force);
    
    //detec the collision betweent the two meshes
    CollisionDetector<MeshType> c;
    c.add_object(mesh);
    c.add_object(mesh2);
    c.check_collisions();
    std::vector<unsigned> collision;
    std::vector<unsigned> collision2;

    //find the corresponding mesh for each node
    for (auto it=c.begin(); it!= c.end(); ++it){
      auto boom = *it;
      Node n = boom.n1;
      if (boom.mesh1 == &mesh)
        collision.push_back(n.index());
      if (boom.mesh1 == &mesh2)
        collision2.push_back(n.index());
    }

    //add the collision constrain to the meshes
    collision_constrain(mesh,mesh2,collision,collision2);
    viewer.set_label(t);
    
    //update with removed nodes
    //clear teh viewer's node
    viewer.clear();
    node_map.clear();
    //update viewer with new positions and new edges
    viewer.add_nodes(mesh.node_begin(), mesh.node_end(), color(color1, color2, color3), node_map);
    viewer.add_edges(mesh.edge_begin(), mesh.edge_end(), node_map);
    viewer.add_nodes(mesh2.node_begin(), mesh2.node_end(), color(color1, color2, color3), node_map);
    viewer.add_edges(mesh2.edge_begin(), mesh2.edge_end(), node_map);

    // These lines slow down the animation for small graphs
    if (mesh.num_nodes() < 100)
      CS207::sleep(0.001);
  }

  return 0;
}