Esempio n. 1
0
void physics_system::contact_listener::EndContact(b2Contact* contact) {
	auto& sys = get_sys();
	auto& cosmos = cosm;

	for (int i = 0; i < 2; ++i) {
		auto fix_a = contact->GetFixtureA();
		auto fix_b = contact->GetFixtureB();

		if (i == 1)
			std::swap(fix_a, fix_b);

		auto body_a = fix_a->GetBody();
		auto body_b = fix_b->GetBody();

		messages::collision_message msg;
		msg.type = messages::collision_message::event_type::END_CONTACT;

		auto subject = cosmos[fix_a->GetUserData()];
		auto collider = cosmos[fix_b->GetUserData()];

		msg.subject = subject;
		msg.collider = collider;

		auto& subject_fixtures = subject.get<components::fixtures>();
		auto& collider_fixtures = collider.get<components::fixtures>();

		auto& collider_physics = collider_fixtures.get_owner_body().get<components::special_physics>();

		if (subject_fixtures.is_friction_ground() && during_step) {
#if FRICTION_FIELDS_COLLIDE
			if (!collider_fixtures.is_friction_ground)
#endif
			{
				for (auto it = collider_physics.owner_friction_grounds.begin(); it != collider_physics.owner_friction_grounds.end(); ++it)
					if ((*it).target == subject_fixtures.get_owner_body())
					{
						auto& fixtures_connected = (*it).fixtures_connected;
						ensure(fixtures_connected > 0);

						--fixtures_connected;

						if (fixtures_connected == 0) {
							 LOG("Unreg: %x", subject_fixtures.get_owner_body().get_id());
							collider_physics.owner_friction_grounds.erase(it);
							sys.rechoose_owner_friction_body(collider_fixtures.get_owner_body());
						}
						else {
							 LOG("Decr: %x", subject_fixtures.get_owner_body().get_id());
						}

						break;
					}
			}
		}

		msg.subject_impact_velocity = -body_a->GetLinearVelocity();
		msg.collider_impact_velocity = -body_b->GetLinearVelocity();
		sys.accumulated_messages.push_back(msg);
	}
}
Esempio n. 2
0
int			main(int ac, char **av, char **env)
{
  t_system		sys;

  (void)av;
  (void)ac;
  if (signal(SIGINT, &handle_sig) == SIG_ERR)
    return (EXIT_FAILURE);
  if (init_sys(&sys, &sys.history, env) == -1)
    return (EXIT_FAILURE);
  get_sys(&sys);
  process_conf_file(&sys);
  aff_prompt(&sys);
  get_cmd_line(&sys);
  unset_termcaps(&sys);
  free_all(&sys);
  if (sys.exit.exit == true)
    return (sys.exit.value);
  return (EXIT_SUCCESS);
}
Esempio n. 3
0
physics_system::contact_listener::~contact_listener() {
	get_sys().b2world->SetContactListener(nullptr);
}
Esempio n. 4
0
physics_system::contact_listener::contact_listener(cosmos& cosm) : cosm(cosm) {
	get_sys().b2world->SetContactListener(this);
}
Esempio n. 5
0
void physics_system::contact_listener::PreSolve(b2Contact* contact, const b2Manifold* oldManifold) {
	auto& sys = get_sys();
	auto& cosmos = cosm;

	messages::collision_message msgs[2];

	for (int i = 0; i < 2; ++i) {
		auto fix_a = contact->GetFixtureA();
		auto fix_b = contact->GetFixtureB();

		if (i == 1)
			std::swap(fix_a, fix_b);

		b2WorldManifold manifold;
		contact->GetWorldManifold(&manifold);

		auto body_a = fix_a->GetBody();
		auto body_b = fix_b->GetBody();

		auto& msg = msgs[i];

		msg.type = messages::collision_message::event_type::PRE_SOLVE;

		auto subject = cosmos[fix_a->GetUserData()];
		auto collider = cosmos[fix_b->GetUserData()];

		msg.subject = subject;
		msg.collider = collider;

		auto& subject_fixtures = subject.get<components::fixtures>();
		auto& collider_fixtures = collider.get<components::fixtures>();

		if (subject_fixtures.is_friction_ground()) {
			// friction fields do not collide with their children
			if (are_connected_by_friction(collider, subject)) {
				contact->SetEnabled(false);
				return;
			}

			auto& collider_physics = collider_fixtures.get_owner_body().get<components::special_physics>();

			for (auto it = collider_physics.owner_friction_grounds.begin(); it != collider_physics.owner_friction_grounds.end(); ++it)
				if ((*it).target == subject_fixtures.get_owner_body())
				{
					contact->SetEnabled(false);
					return;
				}
		}

		const const_entity_handle subject_owner_body = subject.get_owner_body();
		const const_entity_handle collider_owner_body = collider.get_owner_body();

		auto* driver = subject_owner_body.find<components::driver>();

		bool colliding_with_owning_car = driver && driver->owned_vehicle == collider_owner_body;

		if (colliding_with_owning_car) {
			contact->SetEnabled(false);
			return;
		}

		if (subject_fixtures.standard_collision_resolution_disabled() || collider_fixtures.standard_collision_resolution_disabled()) {
			contact->SetEnabled(false);
		}

		msg.subject_collider_and_convex_indices = sys.map_fixture_pointer_to_indices(fix_a, subject);

		msg.point = manifold.points[0];
		msg.point *= METERS_TO_PIXELSf;

		msg.subject_impact_velocity = body_a->GetLinearVelocityFromWorldPoint(manifold.points[0]);
		msg.collider_impact_velocity = body_b->GetLinearVelocityFromWorldPoint(manifold.points[0]);
	}

	sys.accumulated_messages.push_back(msgs[0]);
	sys.accumulated_messages.push_back(msgs[1]);
}
Esempio n. 6
0
void physics_system::contact_listener::BeginContact(b2Contact* contact) {
	auto& sys = get_sys();
	auto& cosmos = cosm;
	auto delta = cosm.get_fixed_delta();

	for (int i = 0; i < 2; ++i) {
		auto fix_a = contact->GetFixtureA();
		auto fix_b = contact->GetFixtureB();

		int numPoints = contact->GetManifold()->pointCount;
		b2WorldManifold worldManifold;
		contact->GetWorldManifold(&worldManifold);

		if (i == 1) {
			std::swap(fix_a, fix_b);
			if (numPoints > 1) {
				std::swap(worldManifold.points[0], worldManifold.points[1]);
				std::swap(worldManifold.separations[0], worldManifold.separations[1]);
			}
			worldManifold.normal *= -1;
		}

		auto body_a = fix_a->GetBody();
		auto body_b = fix_b->GetBody();

		messages::collision_message msg;

		if (fix_a->IsSensor() || fix_b->IsSensor())
			msg.one_is_sensor = true;

		msg.type = messages::collision_message::event_type::BEGIN_CONTACT;

		auto subject = cosmos[fix_a->GetUserData()];
		auto collider = cosmos[fix_b->GetUserData()];

		msg.subject = subject;
		msg.collider = collider;

		auto& subject_fixtures = subject.get<components::fixtures>();
		auto& collider_fixtures = collider.get<components::fixtures>();

		if (subject_fixtures.is_friction_ground()) {
#if FRICTION_FIELDS_COLLIDE
			if (!collider_fixtures.is_friction_ground)
#endif
			{
				auto& collider_physics = collider_fixtures.get_owner_body().get<components::special_physics>();

				bool found_suitable = false;

				// always accept my own children
				if (are_connected_by_friction(collider, subject)) {
					found_suitable = true;
				}
				else if (collider_physics.since_dropped.lasts(cosm.get_timestamp(), delta)) {
					collider_physics.since_dropped.unset();
					found_suitable = true;
				}
				else {
					for (int i = 0; i < 1; i++) {
						const b2Vec2 pointVelOther = body_b->GetLinearVelocityFromWorldPoint(worldManifold.points[i]);
						const auto velOtherPixels = vec2(pointVelOther) * METERS_TO_PIXELSf;

						if (velOtherPixels.length() > 1) {
							const auto angle = vec2(worldManifold.normal).degrees_between(velOtherPixels);

							if (angle > 90) {
								found_suitable = true;
							}
						}

						if (augs::renderer::get_current().debug_draw_friction_field_collisions_of_entering) {
							augs::renderer::get_current().blink_lines.draw_yellow(METERS_TO_PIXELSf*worldManifold.points[i], METERS_TO_PIXELSf* worldManifold.points[i] + vec2(worldManifold.normal).set_length(150));
							augs::renderer::get_current().blink_lines.draw_red(METERS_TO_PIXELSf*worldManifold.points[i], METERS_TO_PIXELSf* worldManifold.points[i] + velOtherPixels);
						}
					}
				}

				if (found_suitable) {
					auto new_owner = subject_fixtures.get_owner_body().get_id();
					auto& grounds = collider_physics.owner_friction_grounds;
					
					components::special_physics::friction_connection connection(new_owner);
					connection.fixtures_connected = 1;

					if (found_in(grounds, new_owner)) {
						auto found = find_in(grounds, new_owner);
						 LOG("Incr: %x", new_owner);

						connection.fixtures_connected = (*found).fixtures_connected + 1;
						grounds.erase(found);
					}
					else {
						 LOG("Reg: %x", new_owner);
					}
					
					grounds.push_back(connection);

					sys.rechoose_owner_friction_body(collider_fixtures.get_owner_body());
				}
			}
		}

		msg.point = worldManifold.points[0];
		msg.point *= METERS_TO_PIXELSf;

		msg.subject_impact_velocity = body_a->GetLinearVelocityFromWorldPoint(worldManifold.points[0]);
		msg.collider_impact_velocity = body_b->GetLinearVelocityFromWorldPoint(worldManifold.points[0]);
		sys.accumulated_messages.push_back(msg);
	}
}
Esempio n. 7
0
/*
 *  Build the contractors
 */
Ctc& StrategyParam::get_ctc() {

	Ctc* ctc;

	System& ext_sys = get_ext_sys(); // <=> original system in case of a solver

	// the first contractor called
	Ctc& hc4=rec(new CtcHC4(ext_sys,ratio_propag,hc4_incremental));

	// Build contractor #2:
	// --------------------------
	// An interval Newton iteration
	// for solving f()=0 where f is
	// a vector-valued function representing
	// the system.
	Ctc* ctcnewton= NULL;

	if (filtering == "acidhc4n" || filtering=="hc4n" || filtering=="3bcidhc4n")
	  ctcnewton= &rec(new CtcNewton(get_sys().f, NEWTON_CEIL, prec, GAUSS_SEIDEL_RATIO));

	if (filtering=="hc4" || filtering=="hc4n") {
		ctc = (!ctcnewton)?
				&hc4 :
				&rec(new CtcCompo(hc4,ctcnewton));
	} else {

		// hc4 inside acid and 3bcid : incremental propagation beginning with the shaved variable
		Ctc& hc44cid=rec(new CtcHC4(ext_sys.ctrs,0.1,true));

		if (filtering=="acidhc4" || filtering=="acidhc4n") {
			// The ACID contractor (component of the contractor  when filtering == "acidhc4")
			Ctc& acidhc4=rec(new CtcAcid(ext_sys,hc44cid,optim));

			// hc4 followed by acidhc4 : the actual contractor used when filtering == "acidhc4"
			ctc=(!ctcnewton)?
					&rec(new CtcCompo(hc4, acidhc4)) :
					&rec(new CtcCompo(hc4, acidhc4, *ctcnewton));
		}

		else if (filtering =="3bcidhc4" || filtering =="3bcidhc4n") {
			// The 3BCID contractor on all variables (component of the contractor when filtering == "3bcidhc4")
			Ctc& c3bcidhc4=rec(new Ctc3BCid(hc44cid));
			// hc4 followed by 3bcidhc4 : the actual contractor used when filtering == "3bcidhc4"

			ctc=(!ctcnewton)?
					&rec(new CtcCompo(hc4, c3bcidhc4)) :
					&rec(new CtcCompo(hc4, c3bcidhc4, *ctcnewton));
		}
		else  {
			ibex_error("StrategyParam: unknown contractor mode");
		}
	}

	// The CtcXNewton contractor

	// corner selection for linearizations : two corners are selected, a random one and its opposite
	vector<LinearRelaxXTaylor::corner_point> cpoints;
	cpoints.push_back(LinearRelaxXTaylor::RANDOM);
	cpoints.push_back(LinearRelaxXTaylor::RANDOM_INV);

	LinearRelax* lr;

	if (lin_relax=="art")
		lr = &rec(new LinearRelaxCombo(ext_sys,LinearRelaxCombo::ART));
	else if  (lin_relax=="compo")
		lr = &rec(new LinearRelaxCombo(ext_sys,LinearRelaxCombo::COMPO));
	else if (lin_relax=="xn")
		lr = &rec(new LinearRelaxXTaylor(ext_sys,cpoints));
	else
		ibex_error("StrategyParam: unknown liner relaxation mode");

	// fixpoint linear relaxation , hc4  with default fix point ratio 0.2

	if (lin_relax=="compo" || lin_relax=="art"|| lin_relax=="xn") {

		//cxn = new CtcLinearRelaxation (*lr, hc44xn);
		Ctc& cxn_poly = rec(new CtcPolytopeHull(*lr, CtcPolytopeHull::ALL_BOX));

		// hc4 inside xnewton loop
		Ctc& hc44xn = rec(new CtcHC4(ext_sys.ctrs,ratio_propag,false));

		Ctc& cxn_compo = rec(new CtcCompo(cxn_poly, hc44xn));

		Ctc& cxn = rec(new CtcFixPoint (cxn_compo, fixpoint_ratio));

		//  the actual contractor  ctc + linear relaxation
		return rec(new CtcCompo  (*ctc, cxn));

	}
	else
		return *ctc;

}
Esempio n. 8
0
System& OptimizerParam::get_ext_sys() {
	if ((*memory())->sys.size()==2) {
		return (ExtendedSystem&) *((*memory())->sys.back()); // already built and recorded
	}
	else return rec(new ExtendedSystem(get_sys(),eq_eps));
}
Esempio n. 9
0
System& StrategyParam::get_ext_sys() {
	return get_sys();
}