void TestApp::check_normalize_180(float input_angle, float output_angle) { CL_Angle angle; angle.set_degrees(input_angle); angle.normalize_180(); float f_angle = angle.to_degrees(); if ( (f_angle < (output_angle - 0.001f)) || (f_angle > (output_angle + 0.001f) ) ) fail(); }
void CL_Sprite::set_base_angle(CL_Angle angle) { float degrees = angle.to_degrees(); if (degrees >= 0.0f) degrees = fmod(degrees, 360.0f); else degrees = fmod(degrees, 360.0f) + 360.0f; impl->base_angle = CL_Angle(degrees, cl_degrees); }
void CL_Sprite::rotate_yaw(CL_Angle angle) { float degrees = angle.to_degrees(); degrees+=impl->angle_yaw.to_degrees(); if (degrees >= 0.0f) degrees = fmod(degrees, 360.0f); else degrees = fmod(degrees, 360.0f) + 360.0f; impl->angle_yaw = CL_Angle(degrees, cl_degrees); }
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 }