Proxy coordinates

Small research into the behavior of Arma 3 model proxy triangles

Introduction

Proxies in a model provide a way to combine multiple separate model files at runtime, possibly dynamically.

The simplest definition for a proxy is a right triangle, where the point at the right angle (1) defines the center where the proxy model will be inserted, the longer leg (1-3) defines the Y axis, and the shorter leg (1-2) defines the Z axis, and the X axis is perpendicular to the triangle in a way that XYZ form a left-hand coordinate system. The size of the triangle can be completely arbitrary, but the longer leg has a length usually double of the shorter leg.

This sounds all straight and simple, but is it?

Point order

To the human eye, it's rather obvious which points of a proxy triangle are points (1), (2) and (3), but how does the game engine differentiate between them?

One of the possible answers is that it's dependent on the vertices being correctly ordered in the vertex list section of the P3D LOD. In official sample models it's not uncommon that point (2) comes after point (3), or before point (1), so this possibility can be ruled out.

The other possible answer is that the points are simply deduced from the shape of the triangle. This can be verified by the moving point (3) parallel to the (1-2) leg of the triangle, and watching the behavior of the linked proxy model in Buldozer. We can observe that once point (3) goes past the halfway point between (1) and (2), the origin of the proxy model seems to jump from (1) to (2), and the model get's rotated 180°.

Thus we can conclude that the insertion point (origin of the proxy coordinates) is simply the vertex at the largest internal angle, the point defining the Z axis is the vertex at the second largest internal angle, and the Y axis is defined by the vertex at the smallest internal angle.

This means that the triangle actually doesn't have to be a right triangle to work as a proxy, the engine can deduce the proxy coordinate system from any arbitrary triangle.

Transformation issues

Overdetermination

Vertex coordinates are stored in a left-handed cartesian 3D coordinate system, meaning that the X, Y and Z axes are all perpendicular to each other. XY define a vertical plane, while Z is the distance from that plane. With this setup, we only need to define the plane in which 2 of the axes are located, and the direction of 1 of those axes on the plane (we know the other one is perpendicular to the first one). The third axis can be defined as the direction perpendicular to both previously defined axes in a way that they form a left-handed system.

If we combine this information with the fact that the proxy triangle seems to define a plane, and the direction of 2 axes, instead of just 1, we may realize that this leads to an overdetermined situation.

We established that the proxy triangle (by visual intuition) must define the Y and Z axes. We also established that a proxy triangle doesn't actually have to be a right triangle.

What happens when the two vectors originating from point (1) and pointing to point (2) and (3) are not actually perpendicular to each other?

2 different results can be considered:

  1. the Y and Z axes of the coordinate system actually follow the directions of (2) and (3), therefore distorting the coordinate system into a non-cartesian system

  2. only one of points (2) and (3) defines an actual axis, and the other point only serves to define the YZ plane

Result possibility 1: distorted coordinates

This possibility can be quickly dismissed by the observations made in the experiment conducted in Point order. By moving point (3), the proxy model doesn't get distorted.

Result possibility 2: only one axis

By further experimenting with moving the points of the triangle, we can conclude that this is indeed the case.

If we try moving point (3) anywhere in the plane of the triangle face, as long as it doesn't cross the halfway point between (1) and (2), the rendered proxy model doesn't seem to be affected at all.

However if we try to move point (2) parallel to the (1-3) line (as long as the angle the (2) remains smaller than the angle at (1)), we may notice that the proxy model starts to tilt.

Thus we can conclude that it is point (2) that actually defines an axis (the Z axis).

Conclusion

From the above experiments we can conclude the following:

  • any arbitrary triangle can be a proxy, doesn't have to be a right triangle

  • the proxy triangle defines the YZ plane

  • the vector from the vertex at the largest internal angle to the vertex at the second largest internal angle defines the direction of the Z axis on the YZ plane

  • the Y axis is perpendicular to Z, and the X axis is perpendicular to both previous axes in a way that XYZ form a left-handed coordinate system

Code

The following is an excerpt from the Arma 3 Object Builder add-on for Blender to decode the proxy coordinate system. The code is incomplete, only presented as a proof of concept.

def get_proxy_axes(proxy_object):
    vert_1, vert_3, vert_2 = find_axis_vertices(proxy_object.data)
    y = (vert_3.co - vert_1.co).normalized()
    z = (vert_2.co - vert_1.co).normalized()
    x = z.cross(y).normalized()
    y = x.cross(z).normalized()
    
    return x, y, z

Last updated