mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
laserpointer: various improvements:
- calculate system of reference vectors to offset the laser start. - as much stuff as possible calculated in ASL, removing all conversions inside loops. - halved the distance in which men are searched. - increased the tolerance when calculating distance.
This commit is contained in:
parent
e7ec905892
commit
74bfc31598
@ -1,46 +1,55 @@
|
||||
// by commy2
|
||||
// by commy2 and CAA-Picard
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_unit", "_range", "_isGreen"];
|
||||
EXPLODE_3_PVT(_this,_unit,_range,_isGreen);
|
||||
|
||||
_unit = _this select 0;
|
||||
_range = _this select 1;
|
||||
_isGreen = _this select 2;
|
||||
_p0Pos = _unit modelToWorld (_unit selectionPosition "righthand");
|
||||
|
||||
_p0 = _unit modelToWorld (_unit selectionPosition "righthand");
|
||||
_d = _unit weaponDirection currentWeapon _unit;
|
||||
// Convert _p0Pos to ASL
|
||||
_p0 = + _p0Pos;
|
||||
if (!surfaceIsWater _p0) then {
|
||||
_p0 = ATLtoASL _p0;
|
||||
};
|
||||
|
||||
_p1 = _p0 vectorAdd (_d vectorMultiply _range);
|
||||
_pA = _p0 vectorAdd (_d vectorMultiply 0.5);
|
||||
// Find a system of orthogonal reference vectors
|
||||
// _v1 points in the direction of the weapon
|
||||
// _v2 points to the right of the weapon
|
||||
// _v3 points to the top side of the weapon
|
||||
_v1 = _unit weaponDirection currentWeapon _unit;
|
||||
_v2 = vectorNormalized (_v1 vectorCrossProduct [0,0,1]);
|
||||
_v3 = _v2 vectorCrossProduct _v1;
|
||||
|
||||
_offset0 = getTerrainHeightASL _p0;
|
||||
_offset1 = getTerrainHeightASL _p1;
|
||||
_offsetA = getTerrainHeightASL _pA;
|
||||
// Offset over the 3 reference axis
|
||||
// This offset could eventually be configured by weapon in the config
|
||||
_offV1 = 0.31;
|
||||
_offV2 = 0;
|
||||
_offV3 = 0.08;
|
||||
|
||||
_p1 = _p1 vectorAdd [0, 0, _offset0 - _offset1];
|
||||
_p0 = _pA vectorAdd [0, 0, _offset0 - _offsetA];
|
||||
// Offset _p0, the start of the laser
|
||||
_p0 = _p0 vectorAdd (_v1 vectorMultiply _offV1) vectorAdd (_v3 vectorMultiply _offV3) vectorAdd (_v2 vectorMultiply _offV2);
|
||||
_p0Pos = _p0Pos vectorAdd (_v1 vectorMultiply _offV1) vectorAdd (_v3 vectorMultiply _offV3) vectorAdd (_v2 vectorMultiply _offV2);
|
||||
// Calculate _p1, the potential end of the laser
|
||||
_p1 = _p0 vectorAdd (_v1 vectorMultiply _range);
|
||||
|
||||
_fnc_getDistance = {
|
||||
//Debugaaa = lineIntersectsObjs [_p0, _p1, objNull, _unit, false, 2];
|
||||
|
||||
_fnc_getDistanceToTerrain = {
|
||||
private "_distance";
|
||||
|
||||
_pX = + _p0;
|
||||
_line = [ATLToASL _p0, ATLToASL _pX];
|
||||
_line = [_p0, _pX];
|
||||
|
||||
_distance = _this;
|
||||
_iteration = _distance;
|
||||
|
||||
while {
|
||||
_iteration > 0.01 / 2
|
||||
_iteration > 0.05 / 2
|
||||
} do {
|
||||
_iteration = _iteration / 2;
|
||||
|
||||
_pX = _p0 vectorAdd (_d vectorMultiply _distance);
|
||||
_pX = _p0 vectorAdd (_v1 vectorMultiply _distance);
|
||||
|
||||
_offsetX = getTerrainHeightASL _pX;
|
||||
|
||||
_pX = _pX vectorAdd [0, 0, _offset0 - _offsetX];
|
||||
|
||||
_line set [1, ATLToASL _pX];
|
||||
_line set [1, _pX];
|
||||
|
||||
_distance = _distance + (([1, -1] select (lineIntersects (_line + [_unit]) || {terrainIntersectASL _line})) * _iteration);
|
||||
|
||||
@ -50,53 +59,60 @@ _fnc_getDistance = {
|
||||
_distance
|
||||
};
|
||||
|
||||
_distance = _range call _fnc_getDistance;
|
||||
// Get distance to nearest object or terrain (excluding men)
|
||||
_distance = _range call _fnc_getDistanceToTerrain;
|
||||
|
||||
// Find all men potentially intercepted by the ray
|
||||
_intermediatePos = _p0 vectorAdd (_v1 vectorMultiply _distance/2);
|
||||
if (!surfaceIsWater _intermediatePos) then {
|
||||
_intermediatePos = ASLtoATL _intermediatePos;
|
||||
};
|
||||
_units = nearestObjects [_intermediatePos, ["Man"], _distance/2];
|
||||
|
||||
_units = nearestObjects [_unit, ["Man"], _distance];
|
||||
_units deleteAt (_units find _unit);
|
||||
|
||||
_fnc_doesIntersect = {
|
||||
_pX = _p0 vectorAdd (_d vectorMultiply (_this select 1));
|
||||
|
||||
_offsetX = getTerrainHeightASL _pX;
|
||||
|
||||
_pX = _pX vectorAdd [0, 0, _offset0 - _o1];
|
||||
|
||||
count ([_this select 0, "FIRE"] intersect [_p0, _pX]) > 0
|
||||
_fnc_doesIntersectWithMan = {
|
||||
_pX = _p0 vectorAdd (_v1 vectorMultiply (_this select 1));
|
||||
if (!surfaceIsWater _pX) then {
|
||||
_pX = ASLtoATL _pX;
|
||||
};
|
||||
count ([_this select 0, "FIRE"] intersect [_p0Pos, _pX]) > 0
|
||||
};
|
||||
|
||||
// Test intersection with nearby men
|
||||
{
|
||||
if ([_x, _distance] call _fnc_doesIntersect) then {
|
||||
_distance = _distance min (_unit distance _x);
|
||||
if ([_x, _distance] call _fnc_doesIntersectWithMan) then {
|
||||
_distance = _distance min ((_unit distance _x) - _offV1);
|
||||
};
|
||||
} forEach _units;
|
||||
|
||||
//systemChat str _distance;
|
||||
if (_distance < 0.5) exitWith {};
|
||||
|
||||
_pL = _p0 vectorAdd (_d vectorMultiply _distance);
|
||||
_pL2 = _p0 vectorAdd (_d vectorMultiply (_distance - 0.5));
|
||||
_pL = _p0 vectorAdd (_v1 vectorMultiply _distance);
|
||||
_pL2 = _p0 vectorAdd (_v1 vectorMultiply (_distance - 0.5));
|
||||
|
||||
_offsetL = getTerrainHeightASL _pL;
|
||||
_offsetL2 = getTerrainHeightASL _pL2;
|
||||
|
||||
_pL = _pL vectorAdd [0, 0, _offset0 - _offsetL];
|
||||
_pL2 = _pL2 vectorAdd [0, 0, _offset0 - _offsetL2];
|
||||
// Convert _pL to pos
|
||||
if (!surfaceIsWater _pL) then {
|
||||
_pL = ASLtoATL _pL;
|
||||
};
|
||||
|
||||
drawLine3D [
|
||||
_p0,
|
||||
_p0Pos,
|
||||
_pL,
|
||||
[[1,0,0,1], [0,1,0,1]] select _isGreen
|
||||
];
|
||||
|
||||
_spL = worldToScreen _pL; //systemChat str _spL;
|
||||
_size = 2 * (_range - (positionCameraToWorld [0,0,0] distance _pL)) / _range;
|
||||
|
||||
_camPos = positionCameraToWorld [0,0,0.2];
|
||||
if (count ([_unit, "FIRE"] intersect [_camPos, _pL]) > 0) exitWith {};
|
||||
if (count ([ACE_player, "FIRE"] intersect [_camPos, _pL]) > 0) exitWith {};
|
||||
if ( terrainIntersect [_camPos, _pL2]) exitWith {};
|
||||
if (lineIntersects [ATLToASL _camPos, ATLToASL _pL2]) exitWith {};
|
||||
|
||||
// Convert _camPos to ASL
|
||||
if (!surfaceIsWater _camPos) then { _camPos = ATLtoASL _camPos; };
|
||||
if ( terrainIntersectASL [_camPos, _pL2]) exitWith {};
|
||||
if ( lineIntersects [_camPos, _pL2]) exitWith {};
|
||||
|
||||
drawIcon3D [
|
||||
format ["\a3\weapons_f\acc\data\collimdot_%1_ca.paa", ["red", "green"] select _isGreen],
|
||||
|
Loading…
Reference in New Issue
Block a user