Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse engineering - Is this a cheap 3D distance function?

I am reverse engineering a game from 1999 and I came across a function which looks to be checking if the player is within range of a 3d point for the triggering of audio sources. The decompiler mangles the code pretty bad but I think I understand it.

// Position Y delta
v1 = * (float * )(this + 16) - LocalPlayerZoneEntry - > y;

// Position X delta
v2 = * (float * )(this + 20) - LocalPlayerZoneEntry - > x;

// Absolute value
if (v1 < 0.0)
    v1 = -v1;

// Absolute value
if (v2 < 0.0)
    v2 = -v2;

// What is going on here?
if (v1 <= v2)
    v1 = v1 * 0.5;
else
    v2 = v2 * 0.5;

// Z position delta
v3 = * (float * )(this + 24) - LocalPlayerZoneEntry - > z;

// Absolute value
if (v3 < 0.0)
    v3 = -v3;

result = v3 + v2 + v1;

// Radius
if (result > * (float * )(this + 28))
    return 0.0;

return result;

Interestingly enough, when in game, it seemed like the triggering was pretty inconsistent and would sometimes be quite a bit off depending on from which side I approached the trigger.

Does anyone have any idea if this was a common algorithm used back in the day?

Note: The types were all added by me so they may be incorrect. I assume that this is a function of type bool.

like image 945
user923 Avatar asked Jul 19 '19 00:07

user923


1 Answers

The best way to visualize a distance function (a metric) is to plot its unit sphere (the set of points at unit distance from origin -- the metric in question is norm induced).

First rewrite it in a more mathematical form:

N(x,y,z) = 0.5*|x| + |y| + |z|          when |x| <= |y|
         = |x| + 0.5*|y| + |z|          otherwise

Let's do that for 2d (assume that z = 0). The absolute values make the function symmetric in the four quadrants. The |x| <= |y| condition makes it symmetric in all the eight sectors. Let's focus on the sector x > 0, y > 0, x <= y. We want to find the curve when N(x,y,0) = 1. For that sector it reduces to 0.5x + y = 1, or y = 1 - 0.5x. We can go and plot that line. For when x > 0, y > 0, x > y, we get x = 1 - 0.5y. Plotting it all gives the following unit 'circle':

octagon

For comparison, here is an Euclidean unit circle overlaid:

with euclidean

In the third dimension it behaves like a taxicab metric, effectively giving you a 'diamond' shaped sphere:

animated

So yes, it is a cheap distance function, though it lacks rotational symmetries.

like image 66
Yakov Galka Avatar answered Nov 02 '22 15:11

Yakov Galka