Armor/Angle/Penetration system

Added by TheCaptain over 6 years ago

A few months ago I started work on a system to calculate damage to armored vehicles by tracking the shots before they impact and calculating damage effects based on speed & damage of round, armor angle, armor thickness. It was more of a project to see if it was possible first, and practical second (especially as the tracking code relies on a somewhat fast framerate to do all of the LOS checks every second).

Right now the code uses script based hitboxes wrapped around different parts of a tank or AFV, and tracks each tank shell or missile locally to see if it's 'about' to intersect any nearby tank hitboxes. If it is, the code fires a 40mm HE shell, and determines if the impact actually was within the designated tank's box. If so, it applies damage if the shell would penetrate. If not, it simply setposses/setvectors the original round back to the impact point (to then hit the ground, tree, or whatever caused the round to miss).

The script hitboxes are annoying to make, as they depend on someone going into oxygen and manually finding 3d coordinates for the tank parts, as well as pivot points for rotating parts. Plus, in my implementation, they're just cubes and don't exactly follow the geometry of the vehicles.

I got hung up on some of the vector math for rotating the turret hitboxes, and determining the angle of impact, and the code is pretty framerate dependent. I used SPON_Los as the basic code to track the los from the front of the rounds, which actually works pretty well. One problem, however, is the arma missiles that wobble all over the place (so their actual average trajectory is not always the 'wobbly' ends of the trajectory).

Some of the custom damage effects I have are simple things like removing the fuel once a vehicle can no longer move to prevent crew jumping out, or removing the cannon (and keeping the magazines) for when a vehicle loses its main gun.

I was going to release it on its own as a script based system, mostly to include in my own multiplayer mission, but something along these lines could help out with the community armor system project.


Replies (15)

RE: Armor/Angle/Penetration system - Added by kju over 6 years ago

Good approach indeed!

q1184 has/is attempting pretty much the same approach as well in ACE from what I know.
It would be great to join forces here, get experts for all parts involved. :)

For the start we will merge zGuba's work with the one from Fincuan;
make it a modular, standalone and at the same time fully ACE compatible release.

So no hurry here. That said, of course it would be very welcome to share your project,
so that others can inspect the system and code as well to help improve it.

RE: Armor/Angle/Penetration system - Added by Squelch over 6 years ago

Your approach sounds very interesting indeed. There is a command in VBS2 that allows objects to be attached to vehicles at given coordinates, if this could be emulated in Arma, then perhaps armour plates, or parts could be attached to the model that are expendable in a penetration system. There is also the angle of the shot which is exposed in VBS2, which I'm sure we could make the very best use of.

I have been toying with the idea of placing a detection shell around the tank that captures any round of significant threat, and tracks the trajectory that way. It could also become the basis of an active defence system. A trigger was tried, but these are slow to register fast moving objects if at all. The other method could be to make the shell destructible or pass through, but with segments as sections with hit values. Once this has been breached the correct damage can be applied to the tank. It is similar to TheCaptains system, but with the detection done on near strike rather than tracking.

I do think that given the limited damage system that Arma enjoys, an increase in the hit point selections could be made. Unfortunately, damage to any part of the tank cannot be controlled or queried, and the overall damage is always taken into consideration.

With a bit of brainstorming, a viable solution can be struck I'm sure.

The removal of the fuel to prevent AI bailing is sublime.

RE: Armor/Angle/Penetration system - Added by TheCaptain over 6 years ago

In my testing, tracking rounds is far less expensive than tracking incoming shells. Time of flight for a sabot shell at under 100m is nearly instant. This means that the tracking has to essentially be local to the firer. If it were on the client that was getting shot, it might not register a shot being fired at all before it was struck, and would need incredibly fast polling.

As is, I had to slow down some projectiles and poll every 10th or 100th of a second to determine if a trajectory was terminal, fire a dummy projectile, and track that all the way to the point of impact. Somewhat expensive, but comparatively cheap if you think of the amount of ammunition being thrown around a modern firefight. As well, the script is local to the firer, so if every client had one missile or gun firing platform, there would probably be only a handful of tracked rounds per client in the air at any given time. Still, until I did a lot of tuning, I was having problems with shells impacting and not being caught by the script. Most of these were due to bugs in the vector code, but I can't guarantee 100% reliability. Then again, neither can real life armor...

Having the angle of the shot as it comes towards a tank would be really helpful if you wanted to modify the damage after it impacted. My approach was to get the angle from firing shells simply because there was no way to get it after the shell had already hit.

My restriction was to get the system 100% script based so I could incorporate it into my mission. Naturally an approach that used addons could be made less finicky.

We'll see how it goes.

RE: Armor/Angle/Penetration system - Added by th3flyboy about 6 years ago

I had a bit of an idea regarding this. Use the vectorDir and vectorUp commands to get the angle of the incoming projectile, and when it impacts, base it on where on the body it impacted, combined with the vectors, if it hits at an angle where it would bounce IRL, then it would ricochet off the vehicle. If not, then it does damage. This could be achieved in a similar manner to the bouncing of smoke grenades or the ricochets of normal bullets.

as for the armor plates, well since there's the new attach to command, I could see making more than just models based on the base gear except with armor plates. I could see using attach to to simulate things like parts of the tank getting shot off.

RE: Armor/Angle/Penetration system - Added by Squelch about 6 years ago

Bouncing of rounds is controlled by the deflecting value of the ammo in config. It only appears to work when the round strikes the ground, and does have some problems with models. Any ammo that has a timer or is non explosive will bounce if it has a deflection value, ie the fuse has not been armed, after the timer has completed the round will explode. It seems the impact fuse and timed fuse are mutually exclusive.

The direction vectors can only be obtained while the round is "alive", so an impact fused round would need to be tested before impact. With Arma2's asynchronous scripting, trying to accurately find the vectors is going to be hard, though not impossible. VBS2 does return the angle of impact, and it is a shame that Arma is lacking in this area.

Appliqué armour might be possible through either taking advantage of the new attachTo command, or by using proxies on the model itself. In both cases the armour layer can be sacrificed. The proxy method would only work if the proxies were considered crew and the crew vulnerable attribute set. This could introduce several complications that would need workarounds, but would allow the armour to be damaged independently of the main model. AttachTo seems favourite right now.

RE: Armor/Angle/Penetration system - Added by Alienfreak about 6 years ago

The "handledamage" EH would perform well.
If it would let you access the shell. But the EH triggers as the round is already gone.

So sadly you cant extract its vector plus its velocity.

The only way is to track your ammo locally and then if the EH pops up somewhere you will have to check which projectile was near the tank and who owned it and stuff.

And then you could just revert all damage done by the shell by the ArmA 2 damage thingy and apply a custom one, based on fictional models of the tank, to the right locations.

So it would be

Fire bullet -> Track the bullet every 0.01 or so. Get its velocity and vector
Tank gets hit -> Eventhandler tells the damage, ammo and attacker. Undo damage by shell -> Get the locally tracked info of the attackers bullets -> Calculate the hit angle/location by comparing the vectors of the vehicle and projectile -> calculate if it would penetrate -> quit or calculate what parts would have been hit -> Exit.

Or something like that ;)

RE: Armor/Angle/Penetration system - Added by q1184 almost 6 years ago

I've recently found a way to obtain the vector of surface normal at the point of impact. It's a dirty exploit of impact effects and the fact this info is available as 'surfNormalX', 'surfNormalY' and 'surfNormalZ' variables at the time of particle FX processing. I actually tested it on soldiers using the blood effect, but same should be possible for vehicles. The idea is to use these variables to set the speed of the particle, like this:
1 class cfgCloudlets 2 { 3 class MySabotArmorHitFX: Default 4 { 5 moveVelocity[] = 6 { 7 "surfNormalX", 8 "surfNormalY", 9 "surfNormalZ" 10 }; 11 }; 12 };
This will send the particle along the normal of the surface at 1 m/s speed.
Next thing you do is assign an onTimerScript (using CBA macros here:) ):
1 onTimerScript = QUOTE(PATHTO(onTimerFX));
And set the frequency of its execution to every frame:
1 timerperiod = 0.01;

In onTimerFX.sqf you do the following:

1. Use nearestObjects to find the vehicle. Check in its variables if it's the first triggering in the recent time, memorize the particle's position (comes in _this). Also set flag that it's been triggered already.
2. If it's been triggered already and this is the second triggering (also at least a frame has passed since), retrieve the current pos (_this) and the previous one you set in a vehicle var. Subtract the latter from the former, and voila - a pretty accurate normal vector :) Set it to a vehicle var or call a processing script.

Some notes on using onTimerScript:
It first goes off at least a frame after the impact event (triggering of handleDamage EH). Sometimes it takes up to 0.3 s. I didn't manage to make it consistently fire 1 frame later - maybe 0.25-0.3 s is the step of particle processing loop in the engine. Due to this, you have to wait until this information is available before proceeding with the damage calculations. Or you can call further processing from this very script. Due to this latency, you probably can't use the first impact position to determine the actual impact point if the vehicle was moving at the time of impact - better use info from tracked projectile. Another downside it brings is within those 0.3 s another projectile might fly in and compromise the whole thing. Some protection against it (like checking impact position, unlikely it'll be the same spot) is possible though.

To modify Alienfreak's algorithm, the whole procedure now looks like this:

Fire bullet -> Track the bullet every frame. Get its velocity, vector and impact point.
Tank gets hit -> Eventhandler tells the damage, ammo and attacker. Undo damage by shell -> Get the locally tracked info of the attackers bullets -> Hang on until the particle FX's info becomes available -> Get the normal vector -> Calculate the hit angle/location -> calculate if it would penetrate -> quit or calculate what parts would have been hit -> Exit.

Hope it helps or inspires someone :)

RE: Armor/Angle/Penetration system - Added by Alienfreak almost 6 years ago

Thats quite neat actually.
So you could (almost) perfectly find out at which angle it did hit the armor of the vehicle.

Sadly I both haven't scripted a lot in ArmA yet (especially not things which involved local and nonlocal a lot) and I don't have so much time to spare... :/

kju or somebody surely could do it in no time :)

RE: Armor/Angle/Penetration system - Added by Vigilante almost 6 years ago

Thus there are:

"surfNormalX",
"surfNormalY",
"surfNormalZ"

but there are also:

"inDirX",
"inDirY",
"inDirZ"

and:

"inSpeed"

RE: Armor/Angle/Penetration system - Added by bizibiz almost 6 years ago

How to extract "Surfnormal" ? I'd like to generate particle when heavy bullet hit the ground, when i read values in a script, i've got 0...

Q1184 did you test your code ? How to use this ? My few test goes wrong.

Thank you.
GoodBye.

RE: Armor/Angle/Penetration system - Added by Vigilante almost 6 years ago

check A2 config... you need to put these variables into the velocity parameter of the drop command... this way you get a particle with a velocity vector of 1 into the vector direction of the normal ... or you use inDir, for the incident angle, i guess (dunno exactly), also inSpeed is available but this aint a vector array but a scalar in m/s (or was is km/h?).

you need to get the position of two particles that appear shortly after each other, with these positional vectors you can calculate a directional vector, with XtoY function from BIS for example. How you get there reliably, i dont know exactly right now.
Its described above to use a timer Script, but i dont think this is necessary since we can configure the drop command with onTimer and beforeDestroy parameters to call scripts on these events... but how to send the result of these scripts to something useful is still a bit shady for me.

RE: Armor/Angle/Penetration system - Added by q1184 almost 6 years ago

Found another way to obtain normal of surface - more reliable than the particle one. It's called from the shell/missile tracker script, right after the impact. A follow-up ammo object is created at last known position of the shell/missile and is given the same velocity vector. This projectile is of class bulletBase and has 'deflecting' parameter set to 180 so it does not disappear at contact with surface. I found that this projectile always deflects exactly along the normal to the surface (don't ask me why lol). Here are excerpts that will help you set it up (tested within ACE so bear with ACE tags)
cfgAmmo:
1 class ace_at_tracker: BulletBase 2 { 3 timetolive = 0.5; 4 explosive = 0; 5 airfriction = 0; 6 hit = 10; 7 indirecthit = 0; 8 deflecting = 180; 9 };

Tracking script called from fired EH:

1 2 #define __cfg configFile >> "CfgAmmo" >> _ammo 3 4 private ["_unit","_weapon","_ammo","_bullet"]; 5 6 _unit = _this select 0; 7 _weapon = _this select 1; 8 _ammo = _this select 4; 9 _bullet = _this select 5; 10 11 if (isNull _bullet) exitWith {}; 12 13 [_bullet,_weapon,_unit,_ammo,velocity _bullet] spawn 14 { 15 private ["_b","_vel0","_v2","_cos","_posASL","_v","_s","_b","_ammo","_b2","_posprev","_bullet","_pos","_spd","_vel"]; 16 _bullet = _this select 0; 17 _weapon = _this select 1; 18 _unit = _this select 2; 19 _ammo = _this select 3; 20 _vel = _this select 4; 21 22 _pos = [0,0,0]; 23 _spd = _vel distance [0,0,0]; 24 25 // *** tracking rocket pos and velocity *** 26 27 while { alive _bullet } do 28 { 29 _posprev = _pos; 30 _pos = getPos _bullet; 31 _posASL = getPosASL _bullet; 32 if (((velocity _bullet) distance [0,0,0]) > 10) then 33 { 34 _vel = velocity _bullet; 35 }; 36 sleep 0.001; 37 }; 38 39 // creating a follower bullet to precisely find the impact point and normal vector 40 41 _b = "ace_at_tracker" createVehicleLocal [_pos select 0,_pos select 1,1000+(_pos select 2)]; 42 _b setVelocity _vel; 43 _b setPos _posprev; 44 _vel0 = _vel; 45 sleep 0.001; 46 while {alive _b} do 47 { 48 _pos = getPos _b; 49 _posASL = getPosASL _b; 50 _vel = velocity _b; 51 _cos = [_vel,_vel0] call ace_sys_missileguidance_fnc_mat_cos3Dvec; 52 if (_cos < 0.99) exitWith //changed direction of flight - ricochet 53 { 54 55 _v = _vel call ace_sys_missileguidance_fnc_mat_Normalize3D; 56 [ format ["pos %1 posASL %2 angle to normal %3 normal %4",_pos,_posASL, 180 - (acos _cos), _v]] call cba_fnc_debug; 57 }; 58 _vel0 = _vel; 59 sleep 0.001; 60 }; 61 }; 62

ace_sys_missileguidance_fnc_mat_cos3Dvec and ace_sys_missileguidance_fnc_mat_Normalize3D are functions that do exactly what the names suggest - find a cosine between 2 3D vectors (from dot product) and normalize a 3D vector.

This way will give a more reliable result within several frames from the impact, and you shouldn't worry about where to store the data or about data from various impacts mixing up.

RE: Armor/Angle/Penetration system - Added by Alienfreak over 5 years ago

You should include a exitwith which checks if it is a Bullet which can harm a tank otherwise you will end up tracking millions of bullets which are not even neededto be tracked...

RE: Armor/Angle/Penetration system - Added by Vigilante over 5 years ago

yeah, i thought about it too whilst i was researching my ideas for CASP_SAS armor/penetration system... the thing is 7.62mm wouldnt do much harm to a tank .. so somehow i need to find/define a value of 'hardness' or smth .. for both the ammunition and the armor part.. ie hardness of projectile needs to be higher then the max value of the armor ... well rather 'energy' than hardness.. or combinations thereof .. times speed etc..

RE: Armor/Angle/Penetration system - Added by Alienfreak over 5 years ago

Just assign a weight to the bullets plus a AP value, which represents if its made to pierce through armour due to shape and stuff.

Then get teh last velocity of the bullet/whatever and make something like weight*velocity*AP and that has to be higher than a value (per vehicle value) or it will be ignored all together.

(1-15/15)