I have vehicles that drive on terrain and have heading, pitch and roll. I am driving myself crazy trying to get a valid heading angle from the Rotation (ie compass heading). Even chatgpt seems stumped unable to avoid results that aren’t affected by pitch and roll. It seems like it should be simple, but I find myself unable to wrap my head around rotations!

Is there a Quaternion to Euler angle function?

We have deliberately avoided using Euler angles in CGE, to avoid Gimbal lock and avoid ambiguous Euler angles (their meaning depends on axis order). In my experience, most problems are solvable easier (and described more precisely) when Euler angles are avoided – e.g. I don’t think you really want Euler angles for what I’d call a compass But in general, to understand your problem 100% precisely some illustration may be helpful, to make sure we think about calculating the same thing.

You have `TCastleTransform.Rotation`

, represented as axis + angle (first 3 components are rotation axis, 4th component is angle in radians). You can convert it to quaternions. You also have `TCastleTransform.Direction`

which is a vector pointing in the direction you’d want to move (if your 3D model follows standard conventions of glTF).

You can do everything with them, and in my experience you can do everything without going into Euler angles To have a compass, just map Direction on plane Y=0 (you can literally set Y component to zero, or just ignore it). The X an Z components of the resulting vector are what you can use for compass arrow direction. You can use ArcTan2 ( ArcTan2 ) to convert it into a simple angle. Like

```
var
FlatDirection: TVector3;
Angle: Single;
begin
FlatDirection := MyTransform.Direction.
FlatDirection.Y := 0;
// now FlatDirection is a 3D vector parallel to Y=const plane
// or get angle like this:
Angle := ArcTan2(FlatDirection.X, FlatDirection.Z);
end;
```

Hopefully this is helpful, if not then – as noted above – some illustration could be helpful. Words “compass heading” are not perfect here, I mean I imagine one interpretation of what this means, but it’s possible I’m wrong

Yes, that is very simple. I was making it complicated.