Scopes - Fixed zero angle prediction

* Corrects the prediction of the (hair-raising!) zero angle calculation in the vanilla-game
This commit is contained in:
ulteq 2017-11-12 12:11:10 +01:00
parent afbc8bfb82
commit 6b68ff426f
6 changed files with 51 additions and 15 deletions

Binary file not shown.

Binary file not shown.

View File

@ -36,10 +36,10 @@ if (!GVAR(atmosphereModeTBH)) then {
}; };
private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then {
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight];
(parseNumber _zeroAngle) (parseNumber _zeroAngle)
} else { } else {
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngle:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, _temperature, _barometricPressure, _relativeHumidity, _bc, _dragModel, _atmosphereModel]; private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, _temperature, _barometricPressure, _relativeHumidity, _bc, _dragModel, _atmosphereModel];
(parseNumber _zeroAngle) (parseNumber _zeroAngle)
}; };

View File

@ -156,10 +156,10 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t
private _cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]]; private _cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]];
if (isNil {_cacheEntry}) then { if (isNil {_cacheEntry}) then {
private _scopeBaseAngle = if (!_useABConfig) then { private _scopeBaseAngle = if (!_useABConfig) then {
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight];
(parseNumber _zeroAngle) (parseNumber _zeroAngle)
} else { } else {
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngle:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel]; private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel];
(parseNumber _zeroAngle) (parseNumber _zeroAngle)
}; };
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]) then { if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]) then {

View File

@ -32,11 +32,11 @@ if (_initSpeedCoef < 0) then {
_initSpeed = _initSpeed * (-1 * _initSpeedCoef); _initSpeed = _initSpeed * (-1 * _initSpeedCoef);
}; };
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _oldZeroRange, _initSpeed, _airFriction, 0]; private _zeroAngle = "ace_advanced_ballistics" callExtension format ["replicateVanillaZero:%1:%2:%3", _oldZeroRange, _initSpeed, _airFriction];
private _vanillaZero = parseNumber _zeroAngle; private _vanillaZero = parseNumber _zeroAngle;
private _trueZero = if (!_advancedBallistics) then { private _trueZero = if (!_advancedBallistics) then {
_zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _newZeroRange, _initSpeed, _airFriction, _boreHeight]; _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _newZeroRange, _initSpeed, _airFriction, _boreHeight];
(parseNumber _zeroAngle) (parseNumber _zeroAngle)
} else { } else {
// Get Weapon and Ammo Configurations // Get Weapon and Ammo Configurations
@ -62,7 +62,7 @@ private _trueZero = if (!_advancedBallistics) then {
_initSpeed = _initSpeed + _ammoTemperatureVelocityShift; _initSpeed = _initSpeed + _ammoTemperatureVelocityShift;
}; };
_zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngle:%1:%2:%3:%4:%5:%6:%7:%8:%9", _newZeroRange, _initSpeed, _boreHeight, GVAR(zeroReferenceTemperature), GVAR(zeroReferenceBarometricPressure), GVAR(zeroReferenceHumidity), _ballisticCoefficients select 0, _dragModel, _atmosphereModel]; _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _newZeroRange, _initSpeed, _boreHeight, GVAR(zeroReferenceTemperature), GVAR(zeroReferenceBarometricPressure), GVAR(zeroReferenceHumidity), _ballisticCoefficients select 0, _dragModel, _atmosphereModel];
(parseNumber _zeroAngle) (parseNumber _zeroAngle)
}; };

View File

@ -152,7 +152,33 @@ double calculateRetard(int DragFunction, double DragCoefficient, double Velocity
return 0.0; return 0.0;
} }
double calculateVanillaZeroAngle(double zeroRange, double muzzleVelocity, double airFriction, double boreHeight) { float replicateVanillaZero(float zeroRange, float muzzleVelocity, float airFriction) {
const float maxDeltaT = 0.05f;
float time = 0.0f;
ace::vector3<float> curShotPos = { 0, 0, 0 };
ace::vector3<float> speed = { muzzleVelocity, 0, 0 };
while (time < 8.0f) {
float distLeft = zeroRange - curShotPos.x();
float traveled = speed.x() * maxDeltaT;
if (distLeft < traveled) {
float deltaT = distLeft / speed.x();
speed -= { 0, GRAVITY * deltaT, 0 };
curShotPos += speed * deltaT;
time += deltaT;
break;
} else {
float deltaT = maxDeltaT;
curShotPos += speed * deltaT;
time += deltaT;
speed += speed * (speed.magnitude() * airFriction * deltaT);
speed -= { 0, GRAVITY * deltaT, 0 };
}
}
return -std::atan(curShotPos.y() / zeroRange);
}
double calculateVanillaZero(double zeroRange, double muzzleVelocity, double airFriction, double boreHeight) {
double zeroAngle = 0.0f; double zeroAngle = 0.0f;
double deltaT = 1.0 / std::max(100.0, zeroRange); double deltaT = 1.0 / std::max(100.0, zeroRange);
@ -197,7 +223,7 @@ double calculateVanillaZeroAngle(double zeroRange, double muzzleVelocity, double
double offset = -std::atan(y / zeroRange); double offset = -std::atan(y / zeroRange);
zeroAngle += offset; zeroAngle += offset;
if (std::abs(offset) < 0.0001f) { if (std::abs(offset) < 0.00001f) {
break; break;
} }
} }
@ -205,7 +231,7 @@ double calculateVanillaZeroAngle(double zeroRange, double muzzleVelocity, double
return zeroAngle; return zeroAngle;
} }
double calculateZeroAngle(double zeroRange, double muzzleVelocity, double boreHeight, double temperature, double pressure, double humidity, double ballisticCoefficient, int dragModel, char* atmosphereModel) { double calculateAdvancedZero(double zeroRange, double muzzleVelocity, double boreHeight, double temperature, double pressure, double humidity, double ballisticCoefficient, int dragModel, char* atmosphereModel) {
double zeroAngle = 0.0f; double zeroAngle = 0.0f;
double deltaT = 1.0 / std::max(100.0, zeroRange); double deltaT = 1.0 / std::max(100.0, zeroRange);
@ -253,7 +279,7 @@ double calculateZeroAngle(double zeroRange, double muzzleVelocity, double boreHe
double offset = -std::atan(y / zeroRange); double offset = -std::atan(y / zeroRange);
zeroAngle += offset; zeroAngle += offset;
if (std::abs(offset) < 0.0001f) { if (std::abs(offset) < 0.00001f) {
break; break;
} }
} }
@ -642,18 +668,28 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function)
strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
EXTENSION_RETURN(); EXTENSION_RETURN();
} else if (!strcmp(mode, "zeroAngleVanilla")) { } else if (!strcmp(mode, "replicateVanillaZero")) {
float zeroRange = strtof(strtok_s(NULL, ":", &next_token), NULL);
float initSpeed = strtof(strtok_s(NULL, ":", &next_token), NULL);
float airFriction = strtof(strtok_s(NULL, ":", &next_token), NULL);
float zeroAngle = replicateVanillaZero(zeroRange, initSpeed, airFriction);
outputStr << DEGREES(zeroAngle);
strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
EXTENSION_RETURN();
} else if (!strcmp(mode, "calcZero")) {
double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL); double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL);
double initSpeed = strtod(strtok_s(NULL, ":", &next_token), NULL); double initSpeed = strtod(strtok_s(NULL, ":", &next_token), NULL);
double airFriction = strtod(strtok_s(NULL, ":", &next_token), NULL); double airFriction = strtod(strtok_s(NULL, ":", &next_token), NULL);
double boreHeight = strtod(strtok_s(NULL, ":", &next_token), NULL); double boreHeight = strtod(strtok_s(NULL, ":", &next_token), NULL);
double zeroAngle = calculateVanillaZeroAngle(zeroRange, initSpeed, airFriction, boreHeight); double zeroAngle = calculateVanillaZero(zeroRange, initSpeed, airFriction, boreHeight);
outputStr << DEGREES(zeroAngle); outputStr << DEGREES(zeroAngle);
strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
EXTENSION_RETURN(); EXTENSION_RETURN();
} else if (!strcmp(mode, "zeroAngle")) { } else if (!strcmp(mode, "calcZeroAB")) {
double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL); double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL);
double muzzleVelocity = strtod(strtok_s(NULL, ":", &next_token), NULL); double muzzleVelocity = strtod(strtok_s(NULL, ":", &next_token), NULL);
double boreHeight = strtod(strtok_s(NULL, ":", &next_token), NULL); double boreHeight = strtod(strtok_s(NULL, ":", &next_token), NULL);
@ -664,7 +700,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function)
int dragModel = strtol(strtok_s(NULL, ":", &next_token), NULL, 10); int dragModel = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
char* atmosphereModel = strtok_s(NULL, ":", &next_token); char* atmosphereModel = strtok_s(NULL, ":", &next_token);
double zeroAngle = calculateZeroAngle(zeroRange, muzzleVelocity, boreHeight, temperature, pressure, humidity, ballisticCoefficient, dragModel, atmosphereModel); double zeroAngle = calculateAdvancedZero(zeroRange, muzzleVelocity, boreHeight, temperature, pressure, humidity, ballisticCoefficient, dragModel, atmosphereModel);
outputStr << DEGREES(zeroAngle); outputStr << DEGREES(zeroAngle);
strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);