Esempio n. 1
0
File: ai.cpp Progetto: mutnig/vdrift
void AI::updateSteer(AI_Car *c)
{
	c->steerlook.clear();

	const BEZIER *curr_patch_ptr = GetCurrentPatch(c->car);
	//if car has no contact with track, just let it roll
	if (!curr_patch_ptr)
	{
		if (!c->last_patch) return;
		//if car is off track, steer the car towards the last patch it was on
		//this should get the car back on track
		else curr_patch_ptr = c->last_patch;
	}

	c->last_patch = curr_patch_ptr; //store the last patch car was on

	BEZIER curr_patch = RevisePatch(curr_patch_ptr, c->use_racingline);

#ifdef VISUALIZE_AI_DEBUG
	c->steerlook.push_back(curr_patch);
#endif

	//if there is no next patch (probably a non-closed track), let it roll
	if (!curr_patch.next_patch) return;

	BEZIER next_patch = RevisePatch(curr_patch.next_patch, c->use_racingline);

	//find the point to steer towards
	float track_width = GetPatchWidthVector(curr_patch).Magnitude();
	float lookahead = track_width * LOOKAHEAD_FACTOR1 +
			c->car->GetVelocity().Magnitude() * LOOKAHEAD_FACTOR2;
	lookahead = 1.0;
	float length = 0.0;
	MATHVECTOR <float, 3> dest_point = GetPatchFrontCenter(next_patch);

	while (length < lookahead)
	{
#ifdef VISUALIZE_AI_DEBUG
		c->steerlook.push_back(next_patch);
#endif

		length += GetPatchDirection(next_patch).Magnitude()*2.0;
		dest_point = GetPatchFrontCenter(next_patch);

		//if there is no next patch for whatever reason, stop lookahead
		if (!next_patch.next_patch)
		{
			length = lookahead;
			break;
		}

		next_patch = RevisePatch(next_patch.next_patch, c->use_racingline);

		//if next patch is a very sharp corner, stop lookahead
		if (GetPatchRadius(next_patch) < LOOKAHEAD_MIN_RADIUS)
		{
			length = lookahead;
			break;
		}
	}

	MATHVECTOR <float, 3> next_position = TransformToWorldspace(dest_point);
	MATHVECTOR <float, 3> car_position = c->car->GetCenterOfMassPosition();
	MATHVECTOR <float, 3> car_orientation = direction::Forward;
	(c->car->GetOrientation()).RotateVector(car_orientation);

	MATHVECTOR <float, 3> desire_orientation = next_position - car_position;

	//car's direction on the horizontal plane
	car_orientation[2] = 0;
	//desired direction on the horizontal plane
	desire_orientation[2] = 0;

	car_orientation = car_orientation.Normalize();
	desire_orientation = desire_orientation.Normalize();

	//the angle between car's direction and unit y vector (forward direction)
	double alpha = Angle(car_orientation[0], car_orientation[1]);

	//the angle between desired direction and unit y vector (forward direction)
	double beta = Angle(desire_orientation[0], desire_orientation[1]);

	//calculate steering angle and direction
	double angle = beta - alpha;

	//angle += steerAwayFromOthers(c, dt, othercars, angle); //sum in traffic avoidance bias

	if (angle > -360.0 && angle <= -180.0)
		angle = -(360.0 + angle);
	else if (angle > -180.0 && angle <= 0.0)
		angle = - angle;
	else if (angle > 0.0 && angle <= 180.0)
		angle = - angle;
	else if (angle > 180.0 && angle <= 360.0)
		angle = 360.0 - angle;

	float optimum_range = c->car->GetOptimumSteeringAngle();
	angle = clamp(angle, -optimum_range, optimum_range);

	float steer_value = angle / c->car->GetMaxSteeringAngle();
	if (steer_value > 1.0) steer_value = 1.0;
	else if (steer_value < -1.0) steer_value = -1.0;

	assert(!isnan(steer_value));
	c->inputs[CARINPUT::STEER_RIGHT] = steer_value;
}
Esempio n. 2
0
File: ai.cpp Progetto: mutnig/vdrift
MATHVECTOR <float, 3> GetPatchDirection(const BEZIER & patch)
{
	return (GetPatchFrontCenter(patch) - GetPatchBackCenter(patch)) * 0.5;
}
Esempio n. 3
0
void AiCarStandard::UpdateSteer()
{
#ifdef VISUALIZE_AI_DEBUG
	steerlook.clear();
#endif

	const Bezier *curr_patch_ptr = GetCurrentPatch(car);

	//if car has no contact with track, just let it roll
	if (!curr_patch_ptr)
	{
		if (!last_patch) return;
		//if car is off track, steer the car towards the last patch it was on
		//this should get the car back on track
		else curr_patch_ptr = last_patch;
	}

	last_patch = curr_patch_ptr; //store the last patch car was on

	Bezier curr_patch = RevisePatch(curr_patch_ptr, use_racingline);

#ifdef VISUALIZE_AI_DEBUG
	steerlook.push_back(curr_patch);
#endif

	// if there is no next patch (probably a non-closed track), let it roll
	if (!curr_patch.GetNextPatch()) return;

	Bezier next_patch = RevisePatch(curr_patch.GetNextPatch(), use_racingline);

	// find the point to steer towards
	float lookahead = 1.0;
	float length = 0.0;
	Vec3 dest_point = GetPatchFrontCenter(next_patch);

	while (length < lookahead)
	{
#ifdef VISUALIZE_AI_DEBUG
		steerlook.push_back(next_patch);
#endif

		length += GetPatchDirection(next_patch).Magnitude()*2.0;
		dest_point = GetPatchFrontCenter(next_patch);

		// if there is no next patch for whatever reason, stop lookahead
		if (!next_patch.GetNextPatch())
		{
			length = lookahead;
			break;
		}

		next_patch = RevisePatch(next_patch.GetNextPatch(), use_racingline);

		// if next patch is a very sharp corner, stop lookahead
		if (GetPatchRadius(next_patch) < LOOKAHEAD_MIN_RADIUS)
		{
			length = lookahead;
			break;
		}
	}

	btVector3 car_position = car->GetCenterOfMass();
	btVector3 car_orientation = quatRotate(car->GetOrientation(), Direction::forward);
	btVector3 desire_orientation = ToBulletVector(dest_point) - car_position;

	//car's direction on the horizontal plane
	car_orientation[2] = 0;
	//desired direction on the horizontal plane
	desire_orientation[2] = 0;

	car_orientation.normalize();
	desire_orientation.normalize();

	//the angle between car's direction and unit y vector (forward direction)
	double alpha = Angle(car_orientation[0], car_orientation[1]);

	//the angle between desired direction and unit y vector (forward direction)
	double beta = Angle(desire_orientation[0], desire_orientation[1]);

	//calculate steering angle and direction
	double angle = beta - alpha;

	//angle += steerAwayFromOthers(c, dt, othercars, angle); //sum in traffic avoidance bias

	if (angle > -360.0 && angle <= -180.0)
		angle = -(360.0 + angle);
	else if (angle > -180.0 && angle <= 0.0)
		angle = - angle;
	else if (angle > 0.0 && angle <= 180.0)
		angle = - angle;
	else if (angle > 180.0 && angle <= 360.0)
		angle = 360.0 - angle;

	float optimum_range = car->GetTire(FRONT_LEFT).getIdealSlipAngle() * SIMD_DEGS_PER_RAD;
	angle = clamp(angle, -optimum_range, optimum_range);

	float steer_value = angle / car->GetMaxSteeringAngle();
	if (steer_value > 1.0) steer_value = 1.0;
	else if (steer_value < -1.0) steer_value = -1.0;

	assert(!std::isnan(steer_value));
	inputs[CarInput::STEER_RIGHT] = steer_value;
}
MATHVECTOR <float, 3> AI_Car_Experimental::GetPatchDirection(const BEZIER & patch)
{
	return GetPatchFrontCenter(patch) - GetPatchBackCenter(patch);
}
Esempio n. 5
0
Vec3 AiCarStandard::GetPatchDirection(const Bezier & patch)
{
	return (GetPatchFrontCenter(patch) - GetPatchBackCenter(patch)) * 0.5;
}