mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Moved all zero angle calculations into the advanced_ballistics.dll
* Speeds up ATragMX * Speeds up RangeCards * Speeds up Scopes
This commit is contained in:
parent
789a169b0e
commit
10cc0ba951
Binary file not shown.
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -2,7 +2,6 @@
|
||||
PREP(adjustScope);
|
||||
PREP(adjustZero);
|
||||
PREP(applyScopeAdjustment);
|
||||
PREP(calculateZeroAngle);
|
||||
PREP(calculateZeroAngleCorrection);
|
||||
PREP(canAdjustZero);
|
||||
PREP(firedEH);
|
||||
|
@ -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
|
@ -19,49 +19,46 @@
|
||||
|
||||
params ["_oldZeroRange", "_newZeroRange", "_boreHeight"/*in cm*/, "_weapon", "_ammo", "_magazine", "_advancedBallistics"];
|
||||
|
||||
// Get Weapon and Ammo Configurations
|
||||
private _AmmoCacheEntry = uiNamespace getVariable format[QEGVAR(advanced_ballistics,%1), _ammo];
|
||||
if (isNil "_AmmoCacheEntry") then {
|
||||
_AmmoCacheEntry = _ammo call EFUNC(advanced_ballistics,readAmmoDataFromConfig);
|
||||
};
|
||||
private _WeaponCacheEntry = uiNamespace getVariable format[QEGVAR(advanced_ballistics,%1), _weapon];
|
||||
if (isNil "_WeaponCacheEntry") then {
|
||||
_WeaponCacheEntry = _weapon call EFUNC(advanced_ballistics,readWeaponDataFromConfig);
|
||||
};
|
||||
|
||||
_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");
|
||||
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 _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 {
|
||||
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 {
|
||||
_AmmoCacheEntry = _ammo call EFUNC(advanced_ballistics,readAmmoDataFromConfig);
|
||||
};
|
||||
private _WeaponCacheEntry = uiNamespace getVariable format[QEGVAR(advanced_ballistics,%1), _weapon];
|
||||
if (isNil "_WeaponCacheEntry") then {
|
||||
_WeaponCacheEntry = _weapon call EFUNC(advanced_ballistics,readWeaponDataFromConfig);
|
||||
};
|
||||
|
||||
_AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable"];
|
||||
_WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"];
|
||||
|
||||
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];
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user