- Статус
- Оффлайн
- Регистрация
- 26 Янв 2020
- Сообщения
- 378
- Реакции
- 157
Просто решил сделать что то интересное, я отдаю себе отчет что ресольвер по велосити это печально. Но место имеет.
Сам ресольвер:
Код нормализации:
Сам ресольвер:
C++:
#include "animation_system.h"
#include "..\ragebot\aim.h"
void resolver::Reset()
{
AnimationLayer layers[15];
auto animstate_reset = player->get_animation_state();
animstate_reset->m_flGoalFeetYaw = 0.0f;
animstate_reset->m_flEyeYaw = 0.0f;
animstate_reset->m_flPitch = 0.0f;
animstate_reset->m_flEyeYaw = 0.0f;
animstate_reset->m_flCurrentFeetYaw = 0.0f;
layers[0].m_flWeight = 0.0f;
layers[1].m_flWeight = 0.0f;
layers[2].m_flWeight = 0.0f;
}
float flAngleMod(float flAngle)
{
return((360.0f / 65536.0f) * ((int32_t)(flAngle * (65536.0f / 360.0f)) & 65535));
}
float ApproachAngle(float flTarget, float flValue, float flSpeed)
{
flTarget = flAngleMod(flTarget);
flValue = flAngleMod(flValue);
float delta = flTarget - flValue;
if (flSpeed < 0)
flSpeed = -flSpeed;
if (delta < -180)
delta += 360;
else if (delta > 180)
delta -= 360;
if (delta > flSpeed)
flValue += flSpeed;
else if (delta < -flSpeed)
flValue -= flSpeed;
else
flValue = flTarget;
return flValue;
}
static auto GetSmoothedVelocity = [](float min_delta, Vector a, Vector b) {
Vector delta = a - b;
float delta_length = delta.Length();
if (delta_length <= min_delta) {
Vector result;
if (-min_delta <= delta_length) {
return a;
}
else {
float iradius = 1.0f / (delta_length + FLT_EPSILON);
return b - ((delta * iradius) * min_delta);
}
}
else {
float iradius = 1.0f / (delta_length + FLT_EPSILON);
return b + ((delta * iradius) * min_delta);
}
};
void resolver::resolve_yaw(player_t* player)
{
player_info_t player_info;
AnimationLayer layers[15];
AnimationLayer moveLayers[3][15];
auto speed_2d = player->m_vecVelocity().Length2D();
memcpy(moveLayers, player->get_animlayers(), sizeof(AnimationLayer) * 15);
auto animState = player->get_animation_state();
float m_flFakeGoalFeetYaw[65];
float m_flChokedTime = TIME_TO_TICKS(player->m_flSimulationTime() - player->m_flOldSimulationTime());
Vector velocity = player->m_vecVelocity();
float spd = velocity.LengthSqr();
if (spd > std::powf(1.2f * 260.0f, 2.f)) {
Vector velocity_normalized = velocity.Normalized();
velocity = velocity_normalized * (1.2f * 260.0f);
}
float v25 = std::clamp(player->m_flDuckAmount() + animState->m_fLandingDuckAdditiveSomething, 0.0f, 1.0f);
float v26 = animState->m_fDuckAmount;
float v27 = m_flChokedTime * 6.0f;
float v28;
// clamp
if ((v25 - v26) <= v27) {
if (-v27 <= (v25 - v26))
v28 = v25;
else
v28 = v26 - v27;
}
else {
v28 = v26 + v27;
}
float flDuckAmount = std::clamp(v28, 0.0f, 1.0f);
Vector animationVelocity = GetSmoothedVelocity(m_flChokedTime * 2000.0f, velocity, player->m_vecVelocity());
float speed = std::fminf(animationVelocity.Length(), 260.0f);
auto weapon = player->m_hActiveWeapon().Get();
auto wpndata = player->m_hActiveWeapon().Get()->get_csweapon_info();
float flMaxMovementSpeed = speed;
float MaxSpeed = player->m_bIsScoped() ? wpndata->flMaxPlayerSpeedAlt : wpndata->flMaxPlayerSpeed;
if (weapon) {
flMaxMovementSpeed = std::fmaxf(MaxSpeed, 0.001f);
}
float flRunningSpeed = speed / (flMaxMovementSpeed * 0.520f);
float flDuckingSpeed = speed / (flMaxMovementSpeed * 0.340f);
float m_flGroundFraction = *(float*)(animState + 0x11C);
flRunningSpeed = std::clamp(flRunningSpeed, 0.0f, 1.0f);
float flYawModifier = (((m_flGroundFraction * -0.3f) - 0.2f) * flRunningSpeed) + 1.0f; // CCSPlayer::MaxDesyncDelta implementation also can be here
if (flDuckAmount > 0.0f) {
float flDuckingSpeed = std::clamp(flDuckingSpeed, 0.0f, 1.0f);
flYawModifier += (flDuckAmount * flDuckingSpeed) * (0.5f - flYawModifier);
}
float flMinBodyYaw = std::fabsf(((float)(uintptr_t(animState) + 0x330)) * flYawModifier);
float flMaxBodyYaw = std::fabsf(((float)(uintptr_t(animState) + 0x334)) * flYawModifier);
float flEyeYaw = player->m_angEyeAngles().y;
float flEyeDiff = std::remainderf(flEyeYaw - m_flFakeGoalFeetYaw[player->EntIndex()], 360.f);
int m_way;
int m_side;
if (!m_engine()->GetPlayerInfo(player->EntIndex(), &player_info))
return;
if (speed_2d <= 0.1)
{
if (layers[3].m_flWeight == 0.0 && layers[3].m_flCycle == 0.0)
{
m_side = 2 * (math::normalize_inline_difference(player->get_animation_state()->m_flEyeYaw, player->get_animation_state()->m_flGoalFeetYaw) <= 0.0) - 1;
m_way = 1;
auto delta = math::normalize_inline_difference(player->m_angEyeAngles().y, player->get_animation_state()->m_flGoalFeetYaw);
}
}
else if ((layers[ANIMATION_LAYER_LEAN].m_flWeight * 1000.0) == (layers[ANIMATION_LAYER_MOVEMENT_MOVE].m_flWeight * 1000.0))
{
float firstDelta = fabs(layers[ANIMATION_LAYER_MOVEMENT_MOVE].m_flPlaybackRate - moveLayers[ANIMATION_LAYER_AIMMATRIX][ANIMATION_LAYER_MOVEMENT_MOVE].m_flPlaybackRate);
float secondDelta = fabs(layers[ANIMATION_LAYER_MOVEMENT_MOVE].m_flPlaybackRate - moveLayers[ANIMATION_LAYER_WEAPON_ACTION_RECROUCH][ANIMATION_LAYER_MOVEMENT_MOVE].m_flPlaybackRate);
float thirdDelta = fabs(layers[ANIMATION_LAYER_MOVEMENT_MOVE].m_flPlaybackRate - moveLayers[ANIMATION_LAYER_AIMMATRIX][ANIMATION_LAYER_MOVEMENT_MOVE].m_flPlaybackRate);
if (firstDelta < secondDelta || thirdDelta <= secondDelta || (secondDelta * 1000.0))
{
if (firstDelta >= thirdDelta && secondDelta > thirdDelta && !(thirdDelta * 1000.0))
{
m_way = 1;
m_side = 1;
}
}
else
{
m_way = 1;
m_side = -1;
}
}
float Left = flEyeYaw - flMinBodyYaw;
float Right = flEyeYaw + flMaxBodyYaw;
auto Left_side_normalize = math::normalize_yaw(player->m_angEyeAngles().y - Left);
auto Right_side_normalize = math::normalize_yaw(player->m_angEyeAngles().y + Right);
if (m_way == 1 || speed_2d > 0.1)
{
if (!player->IsDormant())
{
///ламповый способ апдейтить анимации
player->update_clientside_animation();
for (; player->get_animation_state()->m_flGoalFeetYaw > 180.0f; player->get_animation_state()->m_flGoalFeetYaw = player->get_animation_state()->m_flGoalFeetYaw - 360)
;
for (; player->get_animation_state()->m_flGoalFeetYaw < -180.0f; player->get_animation_state()->m_flGoalFeetYaw = player->get_animation_state()->m_flGoalFeetYaw + 360)
;
*(float*)(uintptr_t(player->get_animation_state()) + 0x80) = player->get_animation_state()->m_flGoalFeetYaw;
///
if (m_side <= 0)
player->get_animation_state()->m_flGoalFeetYaw = Left_side_normalize;
else
player->get_animation_state()->m_flGoalFeetYaw = Right_side_normalize;
}
else
{
///ламповый способ апдейтить анимации
player->update_clientside_animation();
for (; player->get_animation_state()->m_flGoalFeetYaw > 180.0f; player->get_animation_state()->m_flGoalFeetYaw = player->get_animation_state()->m_flGoalFeetYaw - 360)
;
for (; player->get_animation_state()->m_flGoalFeetYaw < -180.0f; player->get_animation_state()->m_flGoalFeetYaw = player->get_animation_state()->m_flGoalFeetYaw + 360)
;
*(float*)(uintptr_t(player->get_animation_state()) + 0x80) = player->get_animation_state()->m_flGoalFeetYaw;
///
if (m_side >= 0)
player->get_animation_state()->m_flGoalFeetYaw = Right_side_normalize;
else
player->get_animation_state()->m_flGoalFeetYaw = Left_side_normalize;
}
}
}
Код нормализации:
C++:
float normalize_inline_difference(float srcAngle, float distAngle)
{
float difference; // xmm1_4
for (; srcAngle > 180.0; srcAngle = srcAngle - 360.0)
;
for (; srcAngle < -180.0; srcAngle = srcAngle + 360.0)
;
for (; distAngle > 180.0; distAngle = distAngle - 360.0)
;
for (; distAngle < -180.0; distAngle = distAngle + 360.0)
;
for (difference = distAngle - srcAngle; difference > 180.0; difference = difference - 360.0)
;
for (; difference < -180.0; difference = difference + 360.0)
;
return difference;
}
Последнее редактирование:

