/////////////////////////////////////////// static Vec3 CalcPedestalUIDir() { // Get the angle from the center of the pedestal to the user's head, // flatten it on the Y axis, and normalize it for angle calculations. Vec3 dir = Input.Head.position - terrainPose.position; dir = dir.XZ.Normalized.X0Y; // Use a 'sticky' algorithm for updating the angle of the UI. We snap // to increments of 60 degrees, but only do it after we've traveled // 20 degrees into the next increment. This prevents the UI from // moving back and forth when the user is wiggling around at the edge // of a snap increment. const float snapAngle = 60; const float stickyAmount = 20; float angle = dir.XZ.Angle(); if (SKMath.AngleDist(angle, uiAngle) > snapAngle / 2 + stickyAmount) { uiAngle = (int)(angle / snapAngle) * snapAngle + snapAngle / 2; } // Turn the angle back into a direction we can use to position the // pedestal return(Vec3.AngleXZ(uiAngle)); }
bool TestAngleDist() { float angleDistA = SKMath.AngleDist(0, 359); float angleDistB = SKMath.AngleDist(359, 0); float angleDistC = SKMath.AngleDist(359, 720); float angleDistD = SKMath.AngleDist(-60, 70); float angleDistE = SKMath.AngleDist(-60, 140); Log.Info($"AngleDist 0 to 359: {angleDistA}"); Log.Info($"AngleDist 359 to 0: {angleDistB}"); Log.Info($"AngleDist 359 to 720: {angleDistC}"); Log.Info($"AngleDist -60 to 70: {angleDistD}"); Log.Info($"AngleDist -60 to 140: {angleDistE}"); if (MathF.Abs(angleDistA - angleDistB) > tolerance) { return(false); } if (MathF.Abs(angleDistA - angleDistC) > tolerance) { return(false); } if (MathF.Abs(angleDistA - 1) > tolerance) { return(false); } if (MathF.Abs(angleDistD - 130) > tolerance) { return(false); } if (MathF.Abs(angleDistE - 160) > tolerance) { return(false); } return(true); }