Seeker system and network enabled laser simulation.

This commit is contained in:
Nou 2015-04-11 18:36:10 -07:00
parent 4188893839
commit 8386c0e22a
11 changed files with 227 additions and 40 deletions

View File

@ -1,3 +1,4 @@
#include "script_component.hpp"
NO_DEDICATED;
["laser_laserOn", {_this call DFUNC(handleLaserOn)}] call EFUNC(common,addEventHandler);
["laser_laserOff", {_this call DFUNC(handleLaserOff)}] call EFUNC(common,addEventHandler);

View File

@ -12,9 +12,18 @@ PREP(findStrongestRay);
PREP(translateToModelSpace);
PREP(translateToWeaponSpace);
PREP(seekerFindLaserSpot);
PREP(laserOn);
PREP(laserOff);
PREP(handleLaserOn);
PREP(handleLaserOff);
PREP(laser_init);
PREP(laserTargetPFH);
ACE_LASERS = [];
ACE_DEFAULT_LASER_CODE = 1001;
ACE_DEFAULT_LASER_CODE = 1001;
GVAR(laserEmitters) = HASH_CREATE;

View File

@ -0,0 +1,8 @@
//fnc_handleLaserOff.sqf
#include "script_component.hpp"
private ["_uuid"];
_uuid = _this select 0;
if(HASH_HASKEY(GVAR(laserEmitters), _uuid)) then {
HASH_REM(GVAR(laserEmitters), _uuid);
};

View File

@ -0,0 +1,7 @@
//fnc_handleLaserOn.sqf
#include "script_component.hpp"
private ["_uuid", "_args"];
_uuid = _this select 0;
_args = _this select 1;
HASH_SET(GVAR(laserEmitters), _uuid, _args);

View File

@ -0,0 +1,16 @@
/*
* Author: Nou
* Turn a laser designator off.
*
* Arguments:
* 0: UUID (from laserOn) <string>
*
* Return value:
* None
*/
#include "script_component.hpp"
private ["_uuid"];
_uuid = _this select 0;
["laser_laserOff", [_uuid]] call EFUNC(common,globalEvent);

View File

@ -0,0 +1,23 @@
/*
* Author: Nou
* Turn a laser designator on.
*
* Arguments:
* 0: Emitter <object>
* 1: Owner <object>
* 2: Method, can be code, which emitter and owner are passed to, an array with a position memory point and weapon name, or an array with a position memory point, a vector begining memory point, and vector ending memory point.
* 3: Wavelength (1550nm is common eye safe) <number>
* 4: Laser code <number>
* 5: Beam divergence (in mils off beam center).
*
* Return value:
* String, UUID for sending to laserOff function.
*/
#include "script_component.hpp"
private ["_uuid", "_args"];
_uuid = format["%1%2%3", floor diag_tickTime, floor random 1000, floor random 10000];
_args = [_uuid, _this];
["laser_laserOn", _args] call EFUNC(common,globalEvent);
_uuid;

View File

@ -32,7 +32,5 @@ if (_d != 0) then {
};
/* Inverse of step 1 */
_q1 set[0, (_q2 select 0) + (_p1 select 0)];
_q1 set[1, (_q2 select 1) + (_p1 select 1)];
_q1 set[2, (_q2 select 2) + (_p1 select 2)];
_q1 = _q2 vectorAdd _p1;
_q1;

View File

@ -5,19 +5,12 @@ _p = _this select 0;
_p1 = _this select 1;
_p2 = _this select 2;
_q1 = [];
_q2 = [];
_u = [];
/* Step 1 */
_q1 set[0, (_p select 0) - (_p1 select 0)];
_q1 set[1, (_p select 1) - (_p1 select 1)];
_q1 set[2, (_p select 2) - (_p1 select 2)];
_u set[0, (_p2 select 0) - (_p1 select 0)];
_u set[1, (_p2 select 1) - (_p1 select 1)];
_u set[2, (_p2 select 2) - (_p1 select 2)];
_u = _u call BIS_fnc_unitVector;
_q1 = _p vectorDiff _p1;
_u = _p2 vectorDiff _p1;
_u = vectorNormalized _u;
_d = sqrt((_u select 1)*(_u select 1) + (_u select 2)*(_u select 2));
/* Step 2 */

View File

@ -0,0 +1,139 @@
/*
* Author: Nou
* Turn a laser designator on.
*
* Arguments:
* 0: Position of seeker (ASL) <position>
* 1: Seeker wavelength sensitivity range, [1550,1550] is common eye safe. <array>
* 2: Seeker laser code. <number>
*
* Return value:
* Array, [Strongest compatible laser spot ASL pos, owner object] Nil array values if nothing found.
*/
#include "script_component.hpp"
private ["_pos", "_seekerWavelengths", "_seekerCode", "_spots", "_buckets", "_excludes", "_bucketIndex", "_finalPos", "_owner", "_obj", "_x", "_method",
"_emitterWavelength", "_laserCode", "_divergence", "_laser", "_laserPos", "_laserDir", "_res", "_bucketPos", "_bucketList", "_c", "_forEachIndex", "_index",
"_testPos", "_finalBuckets", "_largest", "_largestIndex", "_finalBucket", "_owners", "_avgX", "_avgY", "_avgZ", "_count", "_maxOwner", "_maxOwnerIndex", "_finalOwner"];
_pos = _this select 0;
_seekerWavelengths = _this select 1;
_seekerCode = _this select 2;
_spots = [];
_buckets = [];
_excludes = [];
_bucketIndex = 0;
_finalPos = nil;
_finalOwner = nil;
{
_obj = _x select 0;
_owner = _x select 1;
_method = _x select 2;
_emitterWavelength = _x select 3;
_laserCode = _x select 4;
_divergence = _x select 5;
if(alive _obj && {_emitterWavelength >= (_seekerWavelengths select 0)} && {_emitterWavelength <= (_seekerWavelengths select 1)} && {_laserCode == _seekerCode}) then {
_laser = [];
if(IS_CODE(_method)) then {
_laser = _x call _method;
} else {
if(IS_ARRAY(_method)) then {
if(count _method == 2) then {
_laser = [ATLtoASL (_obj modelToWorldVisual (_method select 0)), _obj weaponDirection (_method select 1)];
} else {
if(count _method == 3) then {
_laser = [ATLtoASL (_obj modelToWorldVisual (_method select 0)), (ATLtoASL (_obj modelToWorldVisual (_method select 1))) vectorFromTo (ATLtoASL (_obj modelToWorldVisual (_method select 2)))];
};
};
};
};
_laserPos = _laser select 0;
_laserDir = _laser select 1;
_res = [_laserPos, _laserDir, _divergence] call FUNC(shootCone);
{
_spots pushBack [_x select 0, _owner];
} forEach (_res select 2);
};
} forEach (GVAR(laserEmitters) select 1);
if((count _spots) > 0) then {
_bucketPos = nil;
_bucketList = nil;
_c = 0;
while { count(_spots) != count(_excludes) && _c < (count _spots) } do {
scopeName "mainSearch";
{
if(!(_forEachIndex in _excludes)) then {
_index = _buckets pushBack [_x, [_x]];
_excludes pushBack _forEachIndex;
_bucketPos = _x select 0;
_bucketList = (_buckets select _index) select 1;
breakTo "mainSearch";
};
} forEach _spots;
{
if(!(_forEachIndex in _excludes)) then {
_testPos = (_x select 0);
if(_testPos vectorDistanceSqr _bucketPos <= 100) then {
_bucketList pushBack _x;
_excludes pushBack _forEachIndex;
};
};
} forEach _spots;
_c = _c + 1;
};
_finalBuckets = [];
_largest = -1;
_largestIndex = 0;
{
_index = _finalBuckets pushBack [];
_bucketList = _finalBuckets select _index;
{
_testPos = (_x select 0);
if(!terrainIntersectASL [_pos, _testPos] && {!lineIntersects [_pos, _testPos]}) then {
_bucketList pushBack _x;
};
} forEach (_x select 1);
if((count _bucketList) > _largest) then {
_largest = (count _bucketList);
_largestIndex = _index;
};
} forEach _buckets;
_finalBucket = _finalBuckets select _largestIndex;
_owners = HASH_CREATE;
if(count _finalBucket > 0) then {
_avgX = 0;
_avgY = 0;
_avgZ = 0;
{
player sideChat format["x: %1", _x];
_avgX = _avgX + ((_x select 0) select 0);
_avgY = _avgY + ((_x select 0) select 1);
_avgZ = _avgZ + ((_x select 0) select 2);
_owner = _x select 1;
if(HASH_HASKEY(_owners, _owner)) then {
_count = HASH_GET(_owners, _owner);
HASH_SET(_owners, _owner, _count+1);
} else {
HASH_SET(_owners, _owner, 1);
};
} forEach _finalBucket;
_count = count _finalBucket;
_finalPos = [_avgX/_count, _avgY/_count, _avgZ/_count];
_maxOwner = -1;
_maxOwnerIndex = 0;
{
if((_owners select 1) select _forEachIndex > _maxOwner) then {
_maxOwner = (_owners select 1) select _forEachIndex;
_maxOwnerIndex = _forEachIndex;
};
} forEach (_owners select 0);
_finalOwner = (_owners select 0) select _maxOwnerIndex;
};
};
[_finalPos, _owner];

View File

@ -1,8 +1,13 @@
#include "script_component.hpp"
// #define DEBUG_MODE_FULL
private ["_divergence","_pos","_vec","_longestReturn","_shortestReturn","_resultPositions","_p1","_p2","_p","_v","_cp","_vecRotateMap","_result",
"_resultPos","_distance","_count","_pos2","_radOffset","_offset","_offsetPos","_offsetVector"];
_divergence = 0.3;
_pos = _this select 0;
_vec = _this select 1;
if(count _this > 2) then {
_divergence = _this select 2;
};
_longestReturn = -1000000000;
_shortestReturn = 1000000000;
_resultPositions = [];
@ -10,7 +15,7 @@ _p1 = [0,0,0];
_p2 = +_vec;
_p = (_vec call CBA_fnc_vect2polar);
_v = [(_p select 0), (_p select 1), (_p select 2)+90] call CBA_fnc_polar2vect;
_cp = [_vec, _v] call BIS_fnc_crossProduct;
_cp = _vec vectorCrossProduct _v;
_vecRotateMap = [_cp, _p1, _p2] call FUNC(rotateVectLineGetMap);
@ -24,28 +29,21 @@ if(!isNil "_resultPos") then {
if(_distance > _longestReturn) then {
_longestReturn = _distance;
};
_resultPositions set[(count _resultPositions), _result];
_resultPositions pushBack _result;
#ifdef DEBUG_MODE_FULL
DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
// DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
drawLine3D [ASLtoATL _pos, ASLtoATL _resultPos, [1,0,0,1]];
#endif
};
_count = 8;
_pos2 = [
(_pos select 0)+((_vec select 0)*1000),
(_pos select 1)+((_vec select 1)*1000),
(_pos select 2)+((_vec select 2)*1000)
];
_pos2 = _pos vectorAdd (_vec vectorMultiply 1000);
{
for "_i" from 0 to ceil(_count*_x) do {
_radOffset = random 360;
_offset = [_vecRotateMap, (((360/_count)*_i)+_radOffset) mod 360] call FUNC(rotateVectLine);
_offsetPos = [
(_pos2 select 0)+((_offset select 0)*(_divergence*_x)),
(_pos2 select 1)+((_offset select 1)*(_divergence*_x)),
(_pos2 select 2)+((_offset select 2)*(_divergence*_x))
];
_offsetVector = [_pos, _offsetPos] call BIS_fnc_vectorFromXtoY;
_offsetPos = _pos2 vectorAdd (_offset vectorMultiply (_divergence*_x));
_offsetVector = _pos vectorFromTo _offsetPos;
_result = [_pos, _offsetVector] call FUNC(shootRay);
_resultPos = _result select 0;
if(!isNil "_resultPos") then {
@ -56,9 +54,10 @@ _pos2 = [
if(_distance > _longestReturn) then {
_longestReturn = _distance;
};
_resultPositions set[(count _resultPositions), _result];
_resultPositions pushBack _result;
#ifdef DEBUG_MODE_FULL
DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
// DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]];
drawLine3D [ASLtoATL _pos, ASLtoATL _resultPos, [1,0,0,1]];
#endif
};
};

View File

@ -11,13 +11,8 @@ _lastPos = +_pos;
{
scopeName "mainSearch";
for "_i" from 1 to 10 do {
_nextPos = [
(_lastPos select 0)+((_vec select 0)*_x),
(_lastPos select 1)+((_vec select 1)*_x),
(_lastPos select 2)+((_vec select 2)*_x)
];
if(lineIntersects [_lastPos, _nextPos] || terrainIntersectASL [_lastPos, _nextPos]) then {
_nextPos = _lastPos vectorAdd (_vec vectorMultiply _x);
if(terrainIntersectASL [_lastPos, _nextPos] || {lineIntersects [_lastPos, _nextPos]}) then {
_resultPos = _lastPos;
breakTo "mainSearch";
} else {
@ -25,6 +20,5 @@ _lastPos = +_pos;
_lastPos = _nextPos;
};
};
} forEach _fidelity;
[_resultPos, _distance];