_FORCE_INLINE_ void generate_contacts() {

		// nothing to do, don't generate
		if (best_axis==Vector2(0.0,0.0))
			return;

		callback->collided=true;

		if (!callback->callback)
			return; //only collide, no callback
		static const int max_supports=2;

		Vector2 supports_A[max_supports];
		int support_count_A;
		if (castA) {
			shape_A->get_supports_transformed_cast(motion_A,-best_axis,*transform_A,supports_A,support_count_A);
		} else {
			shape_A->get_supports(transform_A->basis_xform_inv(-best_axis).normalized(),supports_A,support_count_A);
			for(int i=0;i<support_count_A;i++) {
				supports_A[i] = transform_A->xform(supports_A[i]);
			}
		}

		if (withMargin) {

			for(int i=0;i<support_count_A;i++) {
				supports_A[i]+=-best_axis*margin_A;
			}

		}



		Vector2 supports_B[max_supports];
		int support_count_B;
		if (castB) {
			shape_B->get_supports_transformed_cast(motion_B,best_axis,*transform_B,supports_B,support_count_B);
		} else {
			shape_B->get_supports(transform_B->basis_xform_inv(best_axis).normalized(),supports_B,support_count_B);
			for(int i=0;i<support_count_B;i++) {
				supports_B[i] = transform_B->xform(supports_B[i]);
			}
		}

		if (withMargin) {

			for(int i=0;i<support_count_B;i++) {
				supports_B[i]+=best_axis*margin_B;
			}

		}

/*


		print_line("**************************");
		printf("CBK: %p\n",callback->userdata);
		print_line("type A: "+itos(shape_A->get_type()));
		print_line("type B: "+itos(shape_B->get_type()));
		print_line("xform A: "+*transform_A);
		print_line("xform B: "+*transform_B);
		print_line("normal: "+best_axis);
		print_line("depth: "+rtos(best_depth));
		print_line("index: "+itos(best_axis_index));

		for(int i=0;i<support_count_A;i++) {

			print_line("A-"+itos(i)+": "+supports_A[i]);
		}

		for(int i=0;i<support_count_B;i++) {

			print_line("B-"+itos(i)+": "+supports_B[i]);
		}
//*/




		callback->normal=best_axis;
		_generate_contacts_from_supports(supports_A,support_count_A,supports_B,support_count_B,callback);

		if (callback && callback->sep_axis && *callback->sep_axis!=Vector2())
			*callback->sep_axis=Vector2(); //invalidate previous axis (no test)
		//CollisionSolver2DSW::CallbackResult cbk=NULL;
		//cbk(Vector2(),Vector2(),NULL);

	}
	_FORCE_INLINE_ void generate_contacts() {

		// nothing to do, don't generate
		if (best_axis == Vector3(0.0, 0.0, 0.0))
			return;

		if (!callback->callback) {
			//just was checking intersection?
			callback->collided = true;
			if (callback->prev_axis)
				*callback->prev_axis = best_axis;
			return;
		}

		static const int max_supports = 16;

		Vector3 supports_A[max_supports];
		int support_count_A;
		shape_A->get_supports(transform_A->basis.xform_inv(-best_axis).normalized(), max_supports, supports_A, support_count_A);
		for (int i = 0; i < support_count_A; i++) {
			supports_A[i] = transform_A->xform(supports_A[i]);
		}

		if (withMargin) {

			for (int i = 0; i < support_count_A; i++) {
				supports_A[i] += -best_axis * margin_A;
			}
		}

		Vector3 supports_B[max_supports];
		int support_count_B;
		shape_B->get_supports(transform_B->basis.xform_inv(best_axis).normalized(), max_supports, supports_B, support_count_B);
		for (int i = 0; i < support_count_B; i++) {
			supports_B[i] = transform_B->xform(supports_B[i]);
		}

		if (withMargin) {

			for (int i = 0; i < support_count_B; i++) {
				supports_B[i] += best_axis * margin_B;
			}
		}
		/*
		print_line("best depth: "+rtos(best_depth));
		print_line("best axis: "+(best_axis));
		for(int i=0;i<support_count_A;i++) {

			print_line("A-"+itos(i)+": "+supports_A[i]);
		}
		for(int i=0;i<support_count_B;i++) {

			print_line("B-"+itos(i)+": "+supports_B[i]);
		}
*/
		callback->normal = best_axis;
		if (callback->prev_axis)
			*callback->prev_axis = best_axis;
		_generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback);

		callback->collided = true;
		//CollisionSolverSW::CallbackResult cbk=NULL;
		//cbk(Vector3(),Vector3(),NULL);
	}