Arma 3 Scripting

lineIntersectsSurfaces

  • Global argument
  • Arma 3 v1.50

Command · Markdown · JSON · original wiki page

Description

Returns a list of intersections with surfaces and ground from begPosASL to endPosASL. Doesn't return intersection with sea surface. Works underwater, unlike lineIntersects. Hardcoded max distance: 5000m.

Important

  • if begPosASL is under the ground and endPosASL is above it, the command will only return intersection with the ground, this is an engine limitation and none of the intersectXXX commands will work when initiated from under the ground.
  • only a single LOD is checked for intersection. LOD2 will only be checked if LOD1 is unavailable.

Since Arma 3 v2.20, there is an alternative syntax that does multiple checks in parallel, faster than multiple calls.

Syntax

Syntax 1

lineIntersectsSurfaces [begPosASL, endPosASL, ignoreObj1, ignoreObj2, sortMode, maxResults, LOD1, LOD2, returnUnique]

Parameters:

Returns: Array of Arrays with [intersectPosASL, surfaceNormal, intersectObj, parentObject, selectionNames, pathToBisurf]

Syntax 2

since arma3 2.20

lineIntersectsSurfaces [[element1, element2, ...]]

Parameters:

Returns: Array of Arrays with [intersectPosASL, surfaceNormal, intersectObj, parentObject, selectionNames, pathToBisurf]

Examples

Example 1

_intersections = lineIntersectsSurfaces [eyePos player, aimPos chopper, player, chopper, true, -1];

Example 2

arrow = "Sign_Arrow_F" createVehicle [0,0,0];
onEachFrame {
    _ins = lineIntersectsSurfaces [
        AGLToASL positionCameraToWorld [0,0,0],
        AGLToASL positionCameraToWorld [0,0,1000],
        player
    ];
    if (count _ins == 0) exitWith { arrow setPosASL [0,0,0] };
    arrow setPosASL (_ins select 0 select 0);
    arrow setVectorUp (_ins select 0 select 1);
    hintSilent str _ins;
};

Example 3

This should detect glass windows and wire fences (since Arma 3 v1.52):

wirefence = "Land_New_WiredFence_5m_F" createVehicle position player;
arrow = "Sign_Arrow_F" createVehicle [0,0,0];
onEachFrame {
    _ins = lineIntersectsSurfaces [
        AGLToASL positionCameraToWorld [0,0,0],
        AGLToASL positionCameraToWorld [0,0,1000],
        player,
        objNull,
        true,
        1,
        "GEOM",
        "NONE"
    ];
    if (count _ins == 0) exitWith { arrow setPosASL [0,0,0] };
    arrow setPosASL (_ins select 0 select 0);
    arrow setVectorUp (_ins select 0 select 1);
    hintSilent str _ins;
};

Example 4

Alternative syntax to check intersections in parallel. Will draw a redline to the first intersecting object between the player and unit:

private _handle = addMissionEventHandler ["Draw3D", {
    private _enemies = units opfor;
    private _enemyDataArray = _enemies apply { [eyePos player, eyePos _x, player, _x] };

    private _intersections = lineIntersectsSurfaces [_enemyDataArray];
    {
        // No intersections found, draw green '+' icon at unit
        if (_x isEqualTo []) then {
            drawIcon3D [
                "\a3\ui_f\data\gui\cfg\cursors\add_gs.paa",
                [0, 1, 0, 1],
                ASLToAGL (eyePos (_enemies#_forEachIndex)),
                0.5, 0.5, 0,
                str (_enemies#_forEachIndex)
            ];
        } else {
            private _firstIntersection = _x#0;
            // Draw red line and '+' icon to first intersecting object
            drawIcon3D [
                "\a3\ui_f\data\gui\cfg\cursors\add_gs.paa",
                [1, 0, 0, 1],
                ASLToAGL (_firstIntersection#0),
                0.5, 0.5, 0,
                str (_enemies#_forEachIndex) + "- Blocked by " + str (_firstIntersection#2)
            ];
            drawLine3D [
                ASLToAGL (eyePos player),
                ASLToAGL (_firstIntersection#0),
                [1, 0, 0, 1],
                5
            ];
        };
    } forEach _intersections;
}];

See also

lineIntersectsObjs · lineIntersectsWith · lineIntersects · terrainIntersectASL · terrainIntersectAtASL · terrainIntersect · intersect · cursorObject · cursorTarget · checkVisibility

Community notes

Pierre MGI

This command is useful to place weaponholder (and then spawned weapons) on floor of houses, correcting the spawn position (can_collide) to intersect with floor:

MGI_fnc_setPosAGLS = {
    params ["_obj", "_pos"];
    _wh_pos = getPosASL _obj;

    _pos set [2, (ATLToASL _pos select 2) - 10];
    _ins = lineIntersectsSurfaces [_wh_pos, _pos,_obj, objNull, true, 1, "VIEW", "FIRE"];
    _surface_distance = if (count _ins > 0) then [{ (_ins select 0 select 0) distance _wh_pos }, { 0 }];
    _wh_pos set [2, (getPosASL _obj select 2) - (_surface_distance)];
    _weaponholder setPosASL _wh_pos;
};

After the position (_pos) obtained in BIS_fnc_buidingPositions array:

private _weaponHolder = createVehicle ["groundWeaponHolder", _pos, [], 0, "CAN_COLLIDE"];
[_weaponHolder, _pos] call MGI_fnc_setPosAGLS;

Then fill your weapon holder.

Tankbuster

Note that dome_big and dome_small objects have glass roof panels which this function can't see if it intersects those windows