Making the AI aim in 3D

Hey Guys, my current problem is: How do I generate where the AI wants to aim at?
Googling only shows me how to use an equation solver to calculate “movement advancement” (don’t aim at the enemy but before him).

My question is rather: Instead of shooting at “localTranslation” + (0, 1.0, 0) each time, I want something more clever which also takes coverage in consideration. I’ll first describe what I came up with but if you know some good papers or ideas, feel free to recommend them as well:

Okay so first depending on the AI there is an order of hitboxes (this ensures Special Forces first try to shoot in the head where stupid policemen only shoot on the head if the body is covered).

So the Algorithm would iterate over the possible hitboxes in their defined order:
For each hitbox, I want to determine how many percent of it are covered. This ensures that when a player is in cover but has 1 pixel visible, the AI won’t abuse that.

For this, I’d need some subdivided hitbox (manually in blender → I can control the resolution, depending on the box size, or automatically (This would allow to trade off realism for performance)).

Then I would count how many face normals have a low angle to the directional vector (meaning the face is facing us). If that count is too low, the algorithm takes the next hitbox.

Once a hitbox is found which is visible enough, the algorithm simply takes one of the faces’ middlepoint (or I even already have code which returns a random point on a given triangle).

Would you do it differently? I also wonder how good using hitboxes with attachment nodes will work (since you need the offset to be perfectly matching)

1 Like

I haven’t thought this through completely but I wonder if you might have better luck with hit ellipsoids… though for easier math, maybe not true ellipsoids but stretched cylinders.

As I recall, the way normal hit testing happens, we transform the Ray into local space to perform the calculations. If so then you can deal with stretched spheres pretty easily by also scaling the relative Ray location’s x,y,z to that of the ellipsoid.

The problem (to me) with hit boxes is that they have corners that are almost certainly not part of the actual shape… or you have to reduce them to be inside the real shape in which case they lack some of the “meatier” parts. A stretched sphere does not have this issue because it’s more organic and at least in my mind better represents the area I’d want to shoot at.

Furthermore, the math for intersection is easier, I think and could pretty trivially filter on surface “normal”.

1 Like

In what terms? What would be the intention?

While this is true, I think having some overlapping corners might not be that bad, it actually simplifies aiming for players to some degree. If this really leads to a problem, I could still fire a short ray on the actual mesh, to see if this part of the box really is part of the body. But yes, I’ll take primitives in general on my list instead of boxes only.

However my problem is one step before that: Finding out the ray’s direction.

The surface normal for a triangle is just the cross product of 2 of the 3 edges (when you interpret them as vectors, or the 2 vectors from the center to one vertex). However then I’d still need some information about whether or not to invert the normals.
But doesn’t jme already provide a way to access the normals of a Triangle? Like Mesh.getTriangle(i) and then .getNormal()?

Technically, since in JME everything is triangles that would also work for pentagonal cylinders (for example), which also improves aiming when the player is rotated by 45° around the enemy (where you would hit a corner).

But aside from that, does iterating over each tri sound reasonable for such a thing? and then ray-tracing each face until one is in sight (which I forgot to state in the above post actually)

1 Like

For aiming, I don’t think you want pixel/triangle level accuracy. Any real shooter would aim for the “meat” so to speak. You’re never in a million years going to aim for the little part of the elbow.

I’m assuming a person. If I was to decompose a person into hit shapes, at least on the surface, it seems like there are many advantages to using stretched spheres… not the least of which is that the closer to the center of the stretched sphere you are the better the target.

1 Like

Are capsules fine as well or does it have to be spheres? That defeats the closer to the center andantage but close to the end/start of bones it is more accurate

1 Like

The math is harder is all. I was trying to simplify the hit math. Spheres are the easiest collision math you will ever do. It just so happens that they also more accurately represent something you’d want to aim for if you were shooting at something.

Decompose a person into boxes then capsules then stretched spheres. Then tell me, if you were holding a gun and trying to injure someone, which targets would you rather aim for?

Closest to the center of those stretched spheres as possible. Never ever ever the corner of the boxes. And rarely the “corners” of the capsules.

1 Like

This is true, but if you have the torso as sphere, it’s about the shoulders, clavicula etc. It’s unrealistic but due to spread or being quite good covered, one might aim for the shoulders. But I guess this is also doable with proper shapes.

Anyhow, I would use JME’s collideWith(), I actually already have a copy of that code working (so it takes a List of Spatials rather than a Node before recursing). Do you think it’s a bad idea? I mean yes, it’s not separating logic and visuals and yes pure-spherical shapes might be more performant but the cover is most of the time a box.

I think I’ll just try implementing it a bit then

1 Like

I just know from figure drawing, I usually start with a bunch of stretched ovals… Even the torso can be roughed out that way.

Then again, I have one of these that sits on the shelf behind me:

(from back in the “before time” when I used to use a sketch book and this old fashioned thing called a pencil… ie: before the tablet and Manga Studio [which has its own poseable models built in])

Edit: but if you want to avoid math then I guess you are stuck with what JME provides. The downside being that it’s doing a bunch of work you don’t need but it is easier to code to, I guess.

1 Like