Example #1
0
short orient() {
	short angle;
	
	angle = arctan(x,y);
	
	turnAngle(angle);

	rotateBasis(-angle);

	return angle;
}
Example #2
0
/**
 * Horizontal distance covered in a turn
 */
double ProjectedKinematics::turnDistance(Position s1, Position s2, double R) {
	return turnAngle(s1,s2,R)*R;
}
Example #3
0
File: Car.cpp Project: genail/gear
void CarImpl::update1_60() {
	
	static const float BRAKE_POWER = 0.1f;
	static const float ACCEL_POWER = 0.014f;
	static const float SPEED_LIMIT = 15.0f;
	static const float WHEEL_TURN_SPEED = 1.0f / 10.0f;
	static const float TURN_POWER  = (2 * CL_PI / 360.0f) * 2.5f;
	static const float MOV_ALIGN_POWER = TURN_POWER / 2.0f;
	static const float ROT_ALIGN_POWER = TURN_POWER * 0.7f;
	static const float AIR_RESITANCE = 0.003f; // per one speed unit
	static const float DRIFT_SPEED_REDUCTION_RATE = 0.1f;

	// speed limit under what physics angle reduction will be more aggressive
	static const float LOWER_SPEED_ANGLE_REDUCTION = 6.0f;
	// speed limit under what angle difference will be lower than normal
	static const float LOWER_SPEED_ROTATION_REDUCTION = 6.0f;
	// speed limit under what turn power will decrease
	static const float LOWER_SPEED_TURN_REDUCTION = 2.0f;


	// increase the iteration id
	// be aware of 32-bit integer limit
	if (m_iterId != std::numeric_limits<int32_t>::max()) {
		m_iterId++;
	} else {
		m_iterId = 0;
	}

	// don't do anything if car is locked
	if (m_inputLocked) {
		return;
	}
	
	const float prevSpeed = m_speed; // for m_phySpeedDelta

	// apply inputs to speed
	if (m_inputState.brake) {
		m_speed -= BRAKE_POWER;
	} else if (m_inputState.accel) {
		// only if not choking
		if (!isChoking()) {
			m_chocking = false;
			m_speed += (SPEED_LIMIT - m_speed) * ACCEL_POWER;
		} else {
			m_chocking = true;
		}
	}
	
	// rotate steering wheels
	const float diff = m_inputState.turn - m_phyWheelsTurn;

	if (fabs(diff) > WHEEL_TURN_SPEED) {
		m_phyWheelsTurn += diff > 0.0f ? WHEEL_TURN_SPEED : -WHEEL_TURN_SPEED;
	} else {
		m_phyWheelsTurn = m_inputState.turn;
	}

	const float absSpeed = fabs(m_speed);

	// calculate rotations
	if (m_phyWheelsTurn != 0.0f) {

		// rotate corpse and later physics movement
		CL_Angle turnAngle(TURN_POWER * m_phyWheelsTurn, cl_radians);

		if (absSpeed <= LOWER_SPEED_TURN_REDUCTION) {
			// reduce turn if car speed is too low
			turnAngle.set_radians(turnAngle.to_radians() * (absSpeed / LOWER_SPEED_TURN_REDUCTION));
		}

		if (m_speed > 0.0f) {
			m_rotation += turnAngle;
		} else {
			m_rotation -= turnAngle;
		}

		// rotate corpse and physics movement
		if (absSpeed > LOWER_SPEED_ROTATION_REDUCTION) {
			alignRotation(m_phyMoveRot, m_rotation, MOV_ALIGN_POWER);
		} else {
			alignRotation(m_phyMoveRot, m_rotation, MOV_ALIGN_POWER * ((LOWER_SPEED_ROTATION_REDUCTION + 1.0f) - absSpeed));
		}

	} else {

		// align corpse back to physics movement
		alignRotation(m_rotation, m_phyMoveRot, MOV_ALIGN_POWER);

		// makes car stop rotating if speed is too low
		if (absSpeed > LOWER_SPEED_ANGLE_REDUCTION) {
			alignRotation(m_phyMoveRot, m_rotation, ROT_ALIGN_POWER);
		} else {
			alignRotation(m_phyMoveRot, m_rotation, ROT_ALIGN_POWER * ((LOWER_SPEED_ANGLE_REDUCTION + 1.0f) - absSpeed));
		}

		// normalize rotations only when equal
		if (m_rotation == m_phyMoveRot) {
			Workarounds::clAngleNormalize(&m_rotation);
			Workarounds::clAngleNormalize(&m_phyMoveRot);
		}

	}

	Workarounds::clAngleNormalize(&m_phyMoveRot);
	Workarounds::clAngleNormalize(&m_rotation);


	// reduce speed
	const CL_Angle diffAngle = m_rotation - m_phyMoveRot;
	float diffDegAbs = fabs(diffAngle.to_degrees());

	if (diffDegAbs > 0.1f) {

		CL_Angle diffAngleNorm = diffAngle;
		Workarounds::clAngleNormalize180(&diffAngleNorm);

		// 0.0 when going straight, 1.0 when 90 deg, > 1.0 when more than 90 deg
		const float angleRate = fabs(1.0f - (fabs(diffAngleNorm.to_degrees()) - 90.0f) / 90.0f);
		const float speedReduction = -DRIFT_SPEED_REDUCTION_RATE * angleRate;

		if (absSpeed > speedReduction) {
			m_speed += m_speed > 0.0f ? speedReduction : -speedReduction;
		} else {
			m_speed = 0.0f;
		}
	}

	// car cannot travel too quickly
	m_speed -= m_speed * AIR_RESITANCE;

	// calculate next move vector
	const float m_rotationRad = m_phyMoveRot.to_radians();

	m_phyMoveVec.x = cos(m_rotationRad);
	m_phyMoveVec.y = sin(m_rotationRad);

	m_phyMoveVec.normalize();
	m_phyMoveVec *= m_speed;

	// apply movement (invert y)
	m_position.x += m_phyMoveVec.x;
	m_position.y += m_phyMoveVec.y;

	// set speed delta
	m_phySpeedDelta = m_speed - prevSpeed;


#if defined(CLIENT)
#if !defined(NDEBUG)
	// print debug information
	DebugLayer *dbgl = Gfx::Stage::getDebugLayer();

	dbgl->putMessage("speed", cl_format("%1", m_speed));
//	if (!m_level) {
//		const float resistance = m_level->getResistance(m_position.x, m_position.y);
//		dbgl->putMessage("resist", cl_format("%1", resistance));
//	}
#endif // NDEBUG
#endif // CLIENT
}