Beispiel #1
0
void spatial_properties_mixin<false, D>::set_logic_transform(const components::transform t) const {
	if (logic_transform() == t) {
		return;
	}
	
	const auto handle = *static_cast<const D*>(this);
	const auto owner = handle.get_owner_body();

	bool is_only_fixtural = owner.alive() && owner != handle;

	ensure(!is_only_fixtural);
	
	if (handle.has<components::physics>()) {
		ensure(!handle.has<components::transform>());
		const auto& phys = handle.get<components::physics>();
		phys.set_transform(t);
	}
	else {
		handle.get<components::transform>() = t;

		if (handle.has<components::dynamic_tree_node>()) {
			handle.get<components::dynamic_tree_node>().update_proxy();
		}
	}
}
Beispiel #2
0
vec2 basic_spatial_properties_mixin<C, D>::get_effective_velocity() const {
	const auto handle = *static_cast<const D*>(this);
	const auto owner = handle.get_owner_body();

	if (owner.alive()) {
		return owner.get<components::physics>().velocity();
	}
	else if (handle.has<components::position_copying>()) {
		ensure(handle.has<components::transform>());
		return 
			(handle.get<components::transform>().pos - handle.get<components::position_copying>().get_previous_transform().pos)
			* static_cast<float>(handle.get_cosmos().get_fixed_delta().get_steps_per_second());
	}
	
	return{};
}
Beispiel #3
0
bool basic_spatial_properties_mixin<C, D>::has_logic_transform() const {
	const auto handle = *static_cast<const D*>(this);
	const auto owner = handle.get_owner_body();
	
	if (owner.alive() && owner != handle) {
		return true;
	}
	else if (handle.has<components::physics>()) {
		return true;
	}
	else if (handle.has<components::transform>()) {
		return true;
	}

	return false;
}
Beispiel #4
0
components::transform basic_spatial_properties_mixin<C, D>::logic_transform() const {
	const auto handle = *static_cast<const D*>(this);

	const auto owner = handle.get_owner_body();

	if (owner.alive() && owner != handle) {
		return components::fixtures::transform_around_body(handle, owner.logic_transform());
	}
	else if (handle.has<components::physics>()) {
		ensure(!handle.has<components::transform>());
		const auto& phys = handle.get<components::physics>();
		return{ phys.get_position(), phys.get_angle() };
	}
	else if (handle.has<components::wandering_pixels>()) {
		return handle.get<components::wandering_pixels>().reach.center();
	}
	else {
		return handle.get<components::transform>();
	}	
}
Beispiel #5
0
void physics_system::fixtures_construct(const const_entity_handle handle) {
	//ensure(!is_constructed_colliders(handle));
	if (is_constructed_colliders(handle))
		return;

	if (handle.has<components::fixtures>()) {
		const auto colliders = handle.get<components::fixtures>();

		if (colliders.is_activated() && is_constructed_rigid_body(colliders.get_owner_body())) {
			const auto& colliders_data = colliders.get_data();
			auto& cache = get_colliders_cache(handle);

			const auto owner_body_entity = colliders.get_owner_body();
			ensure(owner_body_entity.alive());
			auto& owner_cache = get_rigid_body_cache(owner_body_entity);

			const auto this_cache_id = handle.get_id().pool.indirection_index;
			const auto owner_cache_id = owner_body_entity.get_id().pool.indirection_index;

			owner_cache.correspondent_colliders_caches.push_back(this_cache_id);
			cache.correspondent_rigid_body_cache = owner_cache_id;

			for (size_t ci = 0; ci < colliders_data.colliders.size(); ++ci) {
				const auto& c = colliders_data.colliders[ci];

				b2PolygonShape shape;

				b2FixtureDef fixdef;
				fixdef.density = c.density;
				fixdef.friction = c.friction;
				fixdef.isSensor = c.sensor;
				fixdef.filter = c.filter;
				fixdef.restitution = c.restitution;
				fixdef.shape = &shape;
				fixdef.userData = handle.get_id();

				auto transformed_shape = c.shape;
				transformed_shape.offset_vertices(colliders.get_total_offset());

				std::vector<b2Fixture*> partitioned_collider;

				for (const auto convex : transformed_shape.convex_polys) {
					std::vector<b2Vec2> b2verts(convex.vertices.begin(), convex.vertices.end());

					for (auto& v : b2verts)
						v *= PIXELS_TO_METERSf;

					shape.Set(b2verts.data(), b2verts.size());

					b2Fixture* const new_fix = owner_cache.body->CreateFixture(&fixdef);
					
					ensure(static_cast<short>(ci) < std::numeric_limits<short>::max());
					new_fix->collider_index = static_cast<short>(ci);

					partitioned_collider.push_back(new_fix);
				}

				cache.fixtures_per_collider.push_back(partitioned_collider);
			}
		}
	}
}
Beispiel #6
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]);
}