コード例 #1
0
ファイル: player.cpp プロジェクト: bambams/Cumulate
void Player::Update(float dt)
{
	float max_speed = 10;
	b2Vec2 v = body->GetLinearVelocity();

	if(move_left)
	{
		float mdiff = max_speed + v.x;
		v.x -= mdiff*10*dt;
	}
	if(move_right)
	{
		float mdiff = max_speed - v.x;
		v.x += mdiff*10*dt;
	}
	b2ContactEdge* contactedge = body->GetContactList();
	b2Vec2 contact_normal(0, 0);
	int contacts = 0;
	bool touching_ground = false;
	while(contactedge)
	{
		if(contactedge->contact->IsTouching() && contactedge->contact->IsEnabled())
		{
			touching_ground = true;
			contact_normal += contactedge->contact->GetManifold()->localNormal;
			contacts ++;
		}
		contactedge = contactedge->next;
	}
	contact_normal.x = contact_normal.x/contacts;
	contact_normal.y = contact_normal.y/contacts;

	//Jumping
	if(jump && touching_ground)
	{
		jump = false;
		v += 15*contact_normal;
	}

	//Thrust
	if(jetpack)
	{
		v.y -= 180*dt;
	}

	body->SetLinearVelocity(v);
}
コード例 #2
0
int collision_detection::refineContactNormals(const World::ObjectConstPtr& object,
                                              CollisionResult &res,
                                              double cell_bbx_search_distance,
                                              double allowed_angle_divergence,
                                              bool estimate_depth,
                                              double iso_value,
                                              double metaball_radius_multiple)
{
  if(!object)
  {
    logError("No valid Object passed in, cannot refine Normals!");
    return 0;
  }
  if(res.contact_count < 1)
  {
    logWarn("There do not appear to be any contacts, so there is nothing to refine!");
    return 0;
  }

  int modified = 0;

  // iterate through contacts
  for( collision_detection::CollisionResult::ContactMap::iterator it = res.contacts.begin(); it != res.contacts.end(); ++it)
  {
    std::string contact1 = it->first.first;
    std::string contact2 = it->first.second;
    std::string octomap_name = "";
    std::vector<collision_detection::Contact>& contact_vector = it->second;

    if(      contact1.find("octomap") != std::string::npos ) octomap_name = contact1;
    else if( contact2.find("octomap") != std::string::npos ) octomap_name = contact2;
    else
    {
      continue;
    }

    double cell_size = 0;
    if(!object->shapes_.empty())
    {
      const shapes::ShapeConstPtr& shape = object->shapes_[0];
      boost::shared_ptr<const shapes::OcTree> shape_octree = boost::dynamic_pointer_cast<const shapes::OcTree>(shape);
      if(shape_octree)
      {
        boost::shared_ptr<const octomap::OcTree> octree = shape_octree->octree;
        cell_size = octree->getResolution();
        for(size_t contact_index = 0; contact_index < contact_vector.size(); contact_index++)
        {
          const Eigen::Vector3d& point =   contact_vector[contact_index].pos;
          const Eigen::Vector3d& normal =  contact_vector[contact_index].normal;

          octomath::Vector3 contact_point(point[0], point[1], point[2]);
          octomath::Vector3 contact_normal(normal[0], normal[1], normal[2]);
          octomath::Vector3 diagonal = octomath::Vector3(1,1,1);
          octomath::Vector3 bbx_min = contact_point - diagonal*cell_size*cell_bbx_search_distance;
          octomath::Vector3 bbx_max = contact_point + diagonal*cell_size*cell_bbx_search_distance;
          octomap::point3d_list node_centers;
          octomap::OcTreeBaseImpl<octomap::OcTreeNode, octomap::AbstractOccupancyOcTree>::leaf_bbx_iterator it = octree->begin_leafs_bbx(bbx_min, bbx_max);
          octomap::OcTreeBaseImpl<octomap::OcTreeNode, octomap::AbstractOccupancyOcTree>::leaf_bbx_iterator leafs_end = octree->end_leafs_bbx();
          int count = 0;
          for(  ; it != leafs_end; ++it)
          {
            octomap::point3d pt = it.getCoordinate();
            //double prob = it->getOccupancy();
            if(octree->isNodeOccupied(*it)) // magic number!
            {
              count++;
              node_centers.push_back(pt);
              //logInform("Adding point %d with prob %.3f at [%.3f, %.3f, %.3f]", count, prob, pt.x(), pt.y(), pt.z());
            }
          }
          //logInform("Contact point at [%.3f, %.3f, %.3f], cell size %.3f, occupied cells %d",
          //          contact_point.x(), contact_point.y(), contact_point.z(), cell_size, count);

          //octree->getOccupiedLeafsBBX(node_centers, bbx_min, bbx_max);
          //logError("bad stuff in collision_octomap_filter.cpp; need to port octomap call for groovy");

          octomath::Vector3 n;
          double depth;
          if(getMetaballSurfaceProperties(node_centers, cell_size, iso_value, metaball_radius_multiple,
                                          contact_point, n, depth, estimate_depth))
          {
            // only modify normal if the refinement predicts a "very different" result.
            double divergence = contact_normal.angleTo(n);
            if(divergence > allowed_angle_divergence)
            {
              modified++;
//              logInform("Normals differ by %.3f, changing: [%.3f, %.3f, %.3f] -> [%.3f, %.3f, %.3f]",
//                        divergence,
//                        contact_normal.x(), contact_normal.y(), contact_normal.z(),
//                        n.x(), n.y(), n.z());
              contact_vector[contact_index].normal = Eigen::Vector3d(n.x(), n.y(), n.z());
            }

            if(estimate_depth)
              contact_vector[contact_index].depth = depth;

          }
        }
      }
    }
  }
  return modified;
}