Precise bullet-sprite and bullet-model collision; sloped tank armour

Post your example zscripts/ACS scripts/etc here.
Forum rules
The Projects forums are only for projects. If you are asking questions about a project, either find that project's thread, or start a thread in the General section instead.

Got a cool project idea but nothing else? Put it in the project ideas thread instead!

Projects for any Doom-based engine (especially 3DGE) are perfectly acceptable here too.

Please read the full rules for more details.
Posts: 12
Joined: Sat Mar 04, 2023 8:33 am

Precise bullet-sprite and bullet-model collision; sloped tank armour

Post by N00b »

I hope I have not (yet) wearied ZDoomers with my recent technical topics. This will be the last one for now - I promise :-)

1. Hitmaps.
An older and buggier (plus not all sprites have been done) version of this is showcased in this April video:

The hitmap is in a way similar to a brightmap (hence the name), see this old thread. Its purpose is assigning "damage zones" to a sprite. For example, the GARDA1 sprite of the Nazi soldier on video is being assigned a hitmap with zones Helmet, Head, Chest, Arms, Stomach, Groin, Legs. (Remember Red Orchestra 2?)
The damage dealt to the actor depends on the zone. For example, a headshot is an instant kill, but a helmet hit only deals half of the base damage. With custom damage types or projectiles you can, of course, make rifle shots penetrate the helmet.

The hitmap has to be a Doom format image in a specific palette (SladePalette.pal in the archive - it is a maximal color distance palette taken from Stack Overflow), of the same width and height as the original sprite (offsets are unnecessary).
I just ain't parsing PNG with ZScript when the original Doom image format is that simple.

In the attached file (227KB) you'll be able to shoot actors with BoA Afrika Korps guard sprites using a special projectile pistol, like in the video. The imps (note that some of them are flat and roll-rotated) respond to pressing 'use' instead: if you high five one, it opens the exit door; if you slap its face, you will be subject to punishment.

1. For the hitmaps, pitch black (index 0) and transparent are interchangeable.
2. You can easily adapt the projectile logic for hitscans.
3. Nonzero floorclip will make the visuals inconsistent with shooting results. It either needs to be accounted for or switched off altogether.
4. UDB visual mode shows +ROLLSPRITE actors not in the same way they appear in game.
5. The process of drawing hitmaps manually over the sprites is exceptionally time-consuming even with all the shortcuts, so I planned to write a (semi-) automated tool for this. However, instead of coding (not that I would have done it in a timely manner), with time my plans evolved into the patchwork actors initiative. A tool would still be very useful, any volunteers? :D (I guess not.)
6 (important). In the original hitmap suggestion thread Nash raised a good question. Does anyone have a reference on what kinds of data are possible to overwrite in multiplayer GZDoom? My hitmaps are just binary files placed in a separate '/hitmaps' folder in the pk3 root, they are technically not images; are these multiplayer-protected by hashing?

2. Models.

Two videos of very old versions (however the demo is also quite old):

Here are some 3D model tanks that respond to faux-projectile hitscans designed by Matt. The closer the shell trajectory to the armor plate normal and the thinner the plate, the higher chance the shell will penetrate and damage the tank.
The tanks use the visible higher-detail model and a lower-detail one that is used for detecting collisions with shells. The armor plate thickness is stored in 3D models - just in the names of MD3 groups. I used Maverick Model 3D to simplify BoA models and add this information.
You can test the demo as an IPK3 build (6672KB):

Code: Select all

gzdoom -iwad "tanks.ipk3" -file "doom2.wad" "tanks.pk3"
New controls:
use a tank while outside = ride it
mouse wheel = zoom in or out (1x to 25x)
1, 2, 3 = change shell type
RMB = fix turret and gun position (only the hull can move)

1. As seen in the command, doom2.wad is to be loaded as a PWAD, so you'll need it in the folder.
2. The BoA HUD is here mostly for the moving crosshair. That is quite a lot of code; if you do not need it, you can remove it.
3. More on the crosshair: it is disabled outside the zoomed ("sniper") viewmode because of a difficulty to find a proper position for it, rather than balance reasons: you'll have to dynamically check its position using the same intersection code as for shots. It is not going to be great for performance.
4. Speaking of the performance, a good way to optimize the bruteforce over model triangles would be an octree. It would be better to generate it outside of Doom and just load it on startup.
5. 'External modules' of the tanks (that are not protected by armor) are purely visual and are not used for shell collision. I was just being lazy, it'll be very easy to add them. They would like to see some special effects, such as decreased accuracy for damaged main gun, reduced driveability for tracks, or a fire for the fuel tanks. You will then also want to include internal modules; then you'll just have to consider all ray-triangle intersections instead of just the first one.
6. The code here is way messier even than in my other recent topics, and I remember this being buggier. Please report any problems you stumble upon.
7. Sherman and Tiger are not finished. However the models are done, IIRC you only need to link the actors. There are also some serious problems with MODELDEF and ZScript offsets/scaling for model parts, including the 'working' T-34 and Pz. IV.
8. It might in the end be fruitful to merge all tank classes into one, as I did with the patchwork.
User avatar
Sir Robin
Posts: 537
Joined: Wed Dec 22, 2021 7:02 pm
Graphics Processor: Intel (Modern GZDoom)
Location: Medellin, Colombia

Re: Precise bullet-sprite and bullet-model collision; sloped tank armour

Post by Sir Robin »

Wow, this is amazing. I just recently discovered that I can make my own hitboxes by overriding CanCollide, I assume you're doing something similar here? Mine are simple improvements, like rectangular instead of cubic, and cyndrical and spherical. It sounds like you've got a whole model just for hit maps and check each surface. And you talk about sloped armor so I assume you're comparing the angle of attack to the normal of the hit surface. I thought my code was cool but this is so next level.

I'm trying to take a look at it, the sprite demo worked, but the tanks thing says something about you can't clear the episodes without adding one back. Tested in 4.11.1 and 4.10, both gave that error and won't load.
Posts: 12
Joined: Sat Mar 04, 2023 8:33 am

Re: Precise bullet-sprite and bullet-model collision; sloped tank armour

Post by N00b »

Not sure why the problem might occur, I just drag and drop the two files (pk3 and ipk3) on the executable and then choose the 'tanks' IWAD.
Yes, the tanks code indeed calculates the normalized values of the armor 'plates' (triangle groups in a manually simplified version of the visible model). This effect was the main incentive for me to write this code.
Originally I also wanted to use CanCollideWith, but there was a serious problem that the game would not register hitscan hits on the model parts below the bottom of the actor. And this can happen: the BoA tank movement (which this code is derived from) aligns the hull with the sector slopes. So, in the end, for the rough collision estimation I just use a distance check (IIRC line 248 of bullet.txt). Then I transform the ray into model coordinates and just brute-force ray-triangle intersection over all the triangles, then choose the closest one. Seems to work :-) (but see also pp. 4--5 from the OP).
The crux of all this code is in collision.txt, it was written standalone and then was adapted to BoA tanks (including heavy modifications in the copied BoA code itself, most importantly tanks/tanks.txt), becoming really messy in the process (alas, the original code had to be rewritten almost from scratch because of a poor design decision). C3DCollision reads binary MD3 from the archive (I've expanded ZZYZX's parser used in the player<->3Dmodel collision techdemo). Note that every single tank actor of the same class re-parses the file (I just did not bother with global variables...) ModelHitbox is the base class for the tank hulls (named 'treads' in BoA code) and turrets --- only these parts take part in the collision, see point 5. Only Bullets (based on code by Matt) respect the armor.
I did not really come to terms with MODELDEF offset conventions, so adjustments are in order.

Return to “Script Library”