Moved all zero angle calculations into the advanced_ballistics.dll

* Speeds up ATragMX
* Speeds up RangeCards
* Speeds up Scopes
This commit is contained in:
ulteq 2016-11-09 14:00:25 +01:00 committed by ulteq
parent 789a169b0e
commit 10cc0ba951
11 changed files with 184 additions and 148 deletions

Binary file not shown.

View File

@ -6,7 +6,7 @@ class CfgPatches {
units[] = {"ACE_Item_ATragMX"};
weapons[] = {"ACE_ATragMX"};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ACE_common", "ACE_weather"};
requiredAddons[] = {"ACE_Advanced_Ballistics", "ACE_common", "ACE_weather"};
author = ECSTRING(common,ACETeam);
authors[] = {"Ruthberg"};
url = ECSTRING(main,URL);

View File

@ -29,11 +29,7 @@ private _distance = 0;
while {_velocity > _thresholdVelocity} do {
private _bc = GVAR(targetSolutionInput) select 14;
private _dragModel = GVAR(targetSolutionInput) select 15;
private _drag = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,extensionAvailable), false]) then {
parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _velocity]))
} else {
([_dragModel, _bc, _velocity] call EFUNC(advanced_ballistics,calculateRetardation))
};
private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _velocity]));
_distance = _distance + _velocity * __DELTA_T;
_velocity = _velocity - (_drag * __DELTA_T);
};

View File

@ -90,7 +90,7 @@ _wind1 = [cos(270 - _windDirection * 30) * _windSpeed1, sin(270 - _windDirection
_wind2 = [cos(270 - _windDirection * 30) * _windSpeed2, sin(270 - _windDirection * 30) * _windSpeed2, 0];
_windDrift = 0;
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
_bc = [_bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel] call EFUNC(advanced_ballistics,calculateAtmosphericCorrection);
_bc = parseNumber(("ace_advanced_ballistics" callExtension format["atmosphericCorrection:%1:%2:%3:%4:%5", _bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel]));
};
private ["_speedTotal", "_stepsTotal", "_speedAverage"];
@ -125,11 +125,7 @@ while {_TOF < 15 && (_bulletPos select 1) < _targetRange} do {
_trueSpeed = vectorMagnitude _trueVelocity;
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
private _drag = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,extensionAvailable), false]) then {
parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed]))
} else {
([_dragModel, _bc, _trueSpeed] call EFUNC(advanced_ballistics,calculateRetardation))
};
private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed]));
_bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag);
} else {
_bulletAccel = _trueVelocity vectorMultiply (_trueSpeed * _airFriction);

View File

@ -17,9 +17,6 @@
[] call FUNC(parse_input);
private ["_scopeBaseAngle"];
_scopeBaseAngle = (GVAR(workingMemory) select 3);
private ["_bulletMass", "_boreHeight", "_airFriction", "_muzzleVelocity", "_bc", "_dragModel", "_atmosphereModel"];
_bulletMass = GVAR(workingMemory) select 12;
_boreHeight = GVAR(workingMemory) select 5;
@ -46,12 +43,13 @@ if (!GVAR(atmosphereModeTBH)) then {
_relativeHumidity = 50;
};
{
private _result = [_scopeBaseAngle, _bulletMass, _boreHeight, _airFriction, _muzzleVelocity, _temperature, _barometricPressure, _relativeHumidity, 1000, [0, 0], 0, 0, 0, _zeroRange, _bc, _dragModel, _atmosphereModel, false, 1.5, 0, 0, 0] call FUNC(calculate_solution);
private _offset = (_result select 0) / 60;
_scopeBaseAngle = _scopeBaseAngle + _offset;
if (_offset < 0.01) exitWith {};
} forEach [1, 2, 3];
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];
(parseNumber _zeroAngle)
} 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];
(parseNumber _zeroAngle)
};
GVAR(workingMemory) set [2, _zeroRange];
GVAR(workingMemory) set [3, _scopeBaseAngle];

View File

@ -94,7 +94,7 @@ _wind1 = [cos(270 - _windDirection * 30) * _windSpeed1, sin(270 - _windDirection
_wind2 = [cos(270 - _windDirection * 30) * _windSpeed2, sin(270 - _windDirection * 30) * _windSpeed2, 0];
_windDrift = 0;
if (_useABConfig) then {
_bc = [_bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel] call EFUNC(advanced_ballistics,calculateAtmosphericCorrection);
_bc = parseNumber(("ace_advanced_ballistics" callExtension format["atmosphericCorrection:%1:%2:%3:%4:%5", _bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel]));
};
private ["_airFrictionCoef", "_airDensity"];
@ -131,11 +131,7 @@ while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do {
_trueSpeed = vectorMagnitude _trueVelocity;
if (_useABConfig) then {
private _drag = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,extensionAvailable), false]) then {
parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed]))
} else {
([_dragModel, _bc, _trueSpeed] call EFUNC(advanced_ballistics,calculateRetardation))
};
private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed]));
_bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag);
} else {
_bulletAccel = _trueVelocity vectorMultiply (_trueSpeed * _airFriction * _airFrictionCoef);

View File

@ -158,12 +158,13 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t
_cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4), _zeroRange, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]];
if (isNil {_cacheEntry}) then {
private _scopeBaseAngle = 0;
{
private _offset = [_scopeBaseAngle, _zeroRange, _muzzleVelocity, _airFriction, 1000, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel, _useABConfig] call EFUNC(scopes,calculateZeroAngle);
_scopeBaseAngle = _scopeBaseAngle + _offset;
if (_offset < 0.01) exitWith {};
} forEach [1, 2, 3];
private _scopeBaseAngle = if (!_useABConfig) then {
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight];
(parseNumber _zeroAngle)
} 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];
(parseNumber _zeroAngle)
};
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]) then {
{
private _mvShift = [_ammoConfig select 9, _x] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift);

View File

@ -2,7 +2,6 @@
PREP(adjustScope);
PREP(adjustZero);
PREP(applyScopeAdjustment);
PREP(calculateZeroAngle);
PREP(calculateZeroAngleCorrection);
PREP(canAdjustZero);
PREP(firedEH);

View File

@ -1,84 +0,0 @@
/*
* Author: Ruthberg
* Calculates zero angle
*
* Arguments:
* 0: zero angle <NUMBER>
* 1: zero range <NUMBER>
* 2: muzzle velocity <NUMBER>
* 3: air friction <NUMBER>
* 4: simulation steps <NUMBER>
* 5: bore height <NUMBER>
* 6: temperature <NUMBER>
* 7: barometric pressure <NUMBER>
* 8: relative humidity <NUMBER>
* 9: ballistic coefficient <NUMBER>
* 10: drag model <NUMBER>
* 11: atmosphere model <STRING>
* 12: advanced_ballistics <BOOL>
*
* Return Value:
* 0: zero angle (Degrees) <NUMBER>
*
* Example:
* call ace_scopes_fnc_calculateZeroAngle
*
* Public: No
*/
#include "script_component.hpp"
params [
"_zeroAngle", "_zeroRange", "_muzzleVelocity", "_airFriction", "_simSteps", "_boreHeight",
"_temperature", "_barometricPressure", "_relativeHumidity", "_bc", "_dragModel", "_atmosphereModel",
"_advancedBallistics"
];
private ["_bulletPos", "_bulletVelocity", "_bulletAccel", "_bulletSpeed", "_gravity", "_deltaT"];
_bulletPos = [0, 0, 0];
_bulletVelocity = [0, 0, 0];
_bulletAccel = [0, 0, 0];
_bulletSpeed = 0;
_gravity = [0, sin(_zeroAngle) * -9.80665, cos(_zeroAngle) * -9.80665];
_deltaT = 1 / _simSteps;
private ["_TOF"];
_TOF = 0;
if (_advancedBallistics) then {
_bc = [_bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel] call EFUNC(advanced_ballistics,calculateAtmosphericCorrection);
};
_bulletPos set [0, 0];
_bulletPos set [1, 0];
_bulletPos set [2, -(_boreHeight / 100)];
_bulletVelocity set [0, 0];
_bulletVelocity set [1, Cos(_zeroAngle) * _muzzleVelocity];
_bulletVelocity set [2, Sin(_zeroAngle) * _muzzleVelocity];
while {_TOF < 15 && (_bulletPos select 1) < _zeroRange} do {
_bulletSpeed = vectorMagnitude _bulletVelocity;
if (_advancedBallistics) then {
private _drag = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,extensionAvailable), false]) then {
parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _bulletSpeed]))
} else {
([_dragModel, _bc, _bulletSpeed] call EFUNC(advanced_ballistics,calculateRetardation))
};
_bulletAccel = (vectorNormalized _bulletVelocity) vectorMultiply (-1 * _drag);
} else {
_bulletAccel = _bulletVelocity vectorMultiply (_bulletSpeed * _airFriction);
};
_bulletAccel = _bulletAccel vectorAdd _gravity;
_bulletVelocity = _bulletVelocity vectorAdd (_bulletAccel vectorMultiply _deltaT);
_bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply _deltaT);
_TOF = _TOF + _deltaT;
};
if ((_bulletPos select 1) > 0) then {
_zeroAngle = - atan((_bulletPos select 2) / (_bulletPos select 1));
};
_zeroAngle

View File

@ -19,6 +19,23 @@
params ["_oldZeroRange", "_newZeroRange", "_boreHeight"/*in cm*/, "_weapon", "_ammo", "_magazine", "_advancedBallistics"];
private _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction");
private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed");
private _initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed");
if (_initSpeedCoef > 0) then {
_initSpeed = _initSpeedCoef;
};
if (_initSpeedCoef < 0) then {
_initSpeed = _initSpeed * (-1 * _initSpeedCoef);
};
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _oldZeroRange, _initSpeed, _airFriction, 0];
private _vanillaZero = parseNumber _zeroAngle;
private _trueZero = if (!_advancedBallistics) then {
_zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _newZeroRange, _initSpeed, _airFriction, _boreHeight];
(parseNumber _zeroAngle)
} else {
// Get Weapon and Ammo Configurations
private _AmmoCacheEntry = uiNamespace getVariable format[QEGVAR(advanced_ballistics,%1), _ammo];
if (isNil "_AmmoCacheEntry") then {
@ -32,36 +49,16 @@ if (isNil "_WeaponCacheEntry") then {
_AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable"];
_WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"];
_initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed");
_initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed");
if (_initSpeedCoef > 0) then {
_initSpeed = _initSpeedCoef;
};
if (_initSpeedCoef < 0) then {
_initSpeed = _initSpeed * (-1 * _initSpeedCoef);
};
private _vanillaZero = 0; // in degrees
{
private _offset = [_vanillaZero, _oldZeroRange, _initSpeed, _airFriction, 1000, 0, 0, 0, 0, 0, 0, "", false] call FUNC(calculateZeroAngle);
_vanillaZero = _vanillaZero + _offset;
if (_offset < 0.01) exitWith {};
} forEach [1, 2, 3];
if (_advancedBallistics) then {
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]) then {
private _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _initSpeed] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift);
_initSpeed = _initSpeed + _barrelVelocityShift;
};
_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];
(parseNumber _zeroAngle)
};
private _zeroAngle = 0; // in degrees
{
private _offset = [_zeroAngle, _newZeroRange, _initSpeed, _airFriction, 1000, _boreHeight, GVAR(zeroReferenceTemperature), GVAR(zeroReferenceBarometricPressure), GVAR(zeroReferenceHumidity), _ballisticCoefficients select 0, _dragModel, _atmosphereModel, _advancedBallistics] call FUNC(calculateZeroAngle);
_zeroAngle = _zeroAngle + _offset;
if (_offset < 0.01) exitWith {};
} forEach [1, 2, 3];
private _zeroAngleCorrection = _zeroAngle - _vanillaZero;
private _zeroAngleCorrection = _trueZero - _vanillaZero;
missionNamespace setVariable [format[QGVAR(%1_%2_%3_%4_%5_%6_%7), _oldZeroRange, _newZeroRange, _boreHeight, _weapon, _ammo, _magazine, _advancedBallistics], _zeroAngleCorrection];

View File

@ -5,9 +5,12 @@
#include <vector>
#include <unordered_map>
#include <random>
#include <cmath>
#define DELTA_T 0.02f
#define GRAVITY 9.80665f
#define DEGREES(X) (X * 180 / M_PI)
#define ABSOLUTE_ZERO_IN_CELSIUS -273.15f
#define KELVIN(t) (t - ABSOLUTE_ZERO_IN_CELSIUS)
#define CELSIUS(t) (t + ABSOLUTE_ZERO_IN_CELSIUS)
@ -229,6 +232,113 @@ double calculateRetard(int DragFunction, double DragCoefficient, double Velocity
return 0.0;
}
double calculateVanillaZeroAngle(double zeroRange, double muzzleVelocity, double airFriction, double boreHeight) {
double zeroAngle = 0.0f;
for (int i = 0; i < 10; i++) {
double lx = 0.0f;
double ly = 0.0f;
double px = 0.0f;
double py = -boreHeight / 100.0f;
double gx = std::sin(zeroAngle) * -GRAVITY;
double gy = std::cos(zeroAngle) * -GRAVITY;
double vx = std::cos(zeroAngle) * muzzleVelocity;
double vy = std::sin(zeroAngle) * muzzleVelocity;
double tof = 0.0f;
double v = 0.0f;
while (tof < 8.0f && px < zeroRange) {
lx = px;
ly = py;
v = std::sqrt(vx*vx + vy*vy);
double ax = vx * v * airFriction;
double ay = vy * v * airFriction;
ax += gx;
ay += gy;
px += vx * DELTA_T * 0.5;
py += vy * DELTA_T * 0.5;
vx += ax * DELTA_T;
vy += ay * DELTA_T;
px += vx * DELTA_T * 0.5;
py += vy * DELTA_T * 0.5;
tof += DELTA_T;
}
double y = ly + (zeroRange - lx) * (py - ly) / (px - lx);
double offset = -std::atan(y / zeroRange);
zeroAngle += offset;
if (std::abs(offset) < 0.0001f) {
break;
}
}
return zeroAngle;
}
double calculateZeroAngle(double zeroRange, double muzzleVelocity, double boreHeight, double temperature, double pressure, double humidity, double ballisticCoefficient, int dragModel, char* atmosphereModel) {
double zeroAngle = 0.0f;
ballisticCoefficient = calculateAtmosphericCorrection(ballisticCoefficient, temperature, pressure, humidity, atmosphereModel);
for (int i = 0; i < 10; i++) {
double lx = 0.0f;
double ly = 0.0f;
double px = 0.0f;
double py = -boreHeight / 100.0f;
double gx = std::sin(zeroAngle) * -GRAVITY;
double gy = std::cos(zeroAngle) * -GRAVITY;
double vx = std::cos(zeroAngle) * muzzleVelocity;
double vy = std::sin(zeroAngle) * muzzleVelocity;
double tof = 0.0f;
double v = 0.0f;
while (tof < 8.0f && px < zeroRange) {
lx = px;
ly = py;
v = std::sqrt(vx*vx + vy*vy);
double retard = calculateRetard(dragModel, ballisticCoefficient, v);
double ax = vx / v * -retard;
double ay = vy / v * -retard;
ax += gx;
ay += gy;
px += vx * DELTA_T * 0.5;
py += vy * DELTA_T * 0.5;
vx += ax * DELTA_T;
vy += ay * DELTA_T;
px += vx * DELTA_T * 0.5;
py += vy * DELTA_T * 0.5;
tof += DELTA_T;
}
double y = ly + (zeroRange - lx) * (py - ly) / (px - lx);
double offset = -std::atan(y / zeroRange);
zeroAngle += offset;
if (std::abs(offset) < 0.0001f) {
break;
}
}
return zeroAngle;
}
extern "C"
{
EXPORT void __stdcall RVExtension(char *output, int outputSize, const char *function);
@ -639,6 +749,33 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function)
map->gridBuildingNums.reserve(gridCells);
map->gridSurfaceIsWater.reserve(gridCells);
strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
EXTENSION_RETURN();
} else if (!strcmp(mode, "zeroAngleVanilla")) {
double zeroRange = 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 boreHeight = strtod(strtok_s(NULL, ":", &next_token), NULL);
double zeroAngle = calculateVanillaZeroAngle(zeroRange, initSpeed, airFriction, boreHeight);
outputStr << DEGREES(zeroAngle);
strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
EXTENSION_RETURN();
} else if (!strcmp(mode, "zeroAngle")) {
double zeroRange = 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 temperature = strtod(strtok_s(NULL, ":", &next_token), NULL);
double pressure = strtod(strtok_s(NULL, ":", &next_token), NULL);
double humidity = strtod(strtok_s(NULL, ":", &next_token), NULL);
double ballisticCoefficient = strtod(strtok_s(NULL, ":", &next_token), NULL);
int dragModel = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
char* atmosphereModel = strtok_s(NULL, ":", &next_token);
double zeroAngle = calculateZeroAngle(zeroRange, muzzleVelocity, boreHeight, temperature, pressure, humidity, ballisticCoefficient, dragModel, atmosphereModel);
outputStr << DEGREES(zeroAngle);
strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
EXTENSION_RETURN();
}