Skip to content

Commit

Permalink
Optimized how floats are calculated in Battalion Wars.
Browse files Browse the repository at this point in the history
  • Loading branch information
MeltyPlayer committed Oct 23, 2023
1 parent 904eea5 commit 722de03
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 32 deletions.
31 changes: 31 additions & 0 deletions FinModelUtility/Formats/Modl/Modl Tests/WeirdFloatMathTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace modl.schema.anim {
public class WeirdFloatMathTests {
[Test]
[TestCase(3100000000, -0.00009453f)]
[TestCase(3150000000, -0.005895f)]
[TestCase(3200000000, -0.367431f)]
[TestCase(3250000000, -22.883056f)]
[TestCase(3300000000, -1424.03125f)]
[TestCase((uint) 0x0229C4AB, WeirdFloatMath.C_ZERO)]
[TestCase((uint) 0x38800000, WeirdFloatMath.C_6_10351_EN5)]
[TestCase((uint) 0x3F000000, WeirdFloatMath.C_HALF)]
[TestCase((uint) 0x40400000, WeirdFloatMath.C_3)]
[TestCase((uint) 0x46800000, WeirdFloatMath.C_16384)]
public void TestInterpretAsSingle(uint input, float expectedOutput)
=> Assert.AreEqual(expectedOutput,
WeirdFloatMath.InterpretAsSingle(input),
.000001f);

[Test]
[TestCase(13746744073709551615, -2.6518952414567028E-06d)]
[TestCase(13796744073709551615, -0.0058304183539235046d)]
[TestCase(13846744073709551615, -12.758538758847861d)]
[TestCase(13896744073709551615, -27804.427732706066d)]
[TestCase(13946744073709551615, -60373745.84277343d)]
[TestCase((ulong) 0x4330000000000000, WeirdFloatMath.C_4503599627370496)]
public void TestInterpretAsDouble(ulong input, double expectedOutput)
=> Assert.AreEqual(expectedOutput,
WeirdFloatMath.InterpretAsDouble(input),
.0000001);
}
}
42 changes: 30 additions & 12 deletions FinModelUtility/Formats/Modl/Modl/src/schema/anim/WeirdFloatMath.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
namespace modl.schema.anim {
using System.Runtime.CompilerServices;

namespace modl.schema.anim {
public static class WeirdFloatMath {
/// <summary> 0x38800000 </summary>
public const float C_6_10351_EN5 = 6.103515625E-05f;

/// <summary> 0x0229C4AB </summary>
public const float C_ZERO = 0;

/// <summary> 0x3F000000 </summary>
public const float C_HALF = 0.5f;

/// <summary> 0x40400000 </summary>
public const float C_3 = 3;

/// <summary> 0x46800000 </summary>
public const float C_16384 = 16384f;

/// <summary> 0x4330000000000000 </summary>
public const double C_4503599627370496 = 4503599627370496;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong Concat44(uint first, uint second)
=> ((ulong) first << 32) | second;

public static double InterpretAsDouble(ulong value) {
Span<byte> bytes = stackalloc byte[8];
BitConverter.TryWriteBytes(bytes, value);
return BitConverter.ToDouble(bytes);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe double InterpretAsDouble(ulong value)
=> *(double*) (&value);

public static float InterpretAsSingle(uint value) {
Span<byte> bytes = stackalloc byte[4];
BitConverter.TryWriteBytes(bytes, value);
return BitConverter.ToSingle(bytes);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe float InterpretAsSingle(uint value)
=> *(float*) (&value);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double CreateWeirdDoubleFromUInt32(uint value)
=> WeirdFloatMath.InterpretAsDouble(
WeirdFloatMath.Concat44(0x43300000, value)) -
WeirdFloatMath.InterpretAsDouble(0x4330000000000000);
C_4503599627370496;
}
}
37 changes: 19 additions & 18 deletions FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw1/Bw1Anim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,27 +128,29 @@ public void Parse3PositionValuesFrom2UShorts_(

public bool Parse4RotationValuesFrom3UShorts_(IBinaryReader br,
Span<double> outValues) {
var first_ushort = br.ReadUInt16();
var second_ushort = br.ReadUInt16();
var third_ushort = br.ReadUInt16();
Span<ushort> shorts = stackalloc ushort[3];
br.ReadUInt16s(shorts);
var first_ushort = shorts[0];
var second_ushort = shorts[1];
var third_ushort = shorts[2];

var const_for_out_value_2 = WeirdFloatMath.InterpretAsSingle(0x38000000);
var const_for_out_value_2 = WeirdFloatMath.C_6_10351_EN5;

var out_x =
((WeirdFloatMath.InterpretAsDouble(WeirdFloatMath.Concat44(
0x43300000,
(uint) (first_ushort &
0x7fff))) -
WeirdFloatMath.InterpretAsDouble(0x4330000000000000)) -
WeirdFloatMath.InterpretAsSingle(0x46800000)) *
WeirdFloatMath.InterpretAsSingle(0x38800000);
((WeirdFloatMath.InterpretAsDouble(
WeirdFloatMath.Concat44(
0x43300000,
(uint) (first_ushort & 0x7fff))) -
WeirdFloatMath.C_4503599627370496) -
WeirdFloatMath.C_16384) *
WeirdFloatMath.C_6_10351_EN5;
var out_y =
((WeirdFloatMath.InterpretAsDouble(
WeirdFloatMath.Concat44(0x43300000,
(uint) (second_ushort & 0x7fff))) -
WeirdFloatMath.InterpretAsDouble(0x4330000000000000)) -
WeirdFloatMath.InterpretAsSingle(0x46800000)) *
WeirdFloatMath.InterpretAsSingle(0x38800000);
WeirdFloatMath.C_4503599627370496) -
WeirdFloatMath.C_16384) *
WeirdFloatMath.C_6_10351_EN5;
var third_parsed_thing =
WeirdFloatMath.CreateWeirdDoubleFromUInt32(third_ushort);

Expand All @@ -163,17 +165,16 @@ public bool Parse4RotationValuesFrom3UShorts_(IBinaryReader br,
((1 - out_x * out_x) - out_y * out_y) - out_z * out_z;
var out_w = 0d;
if (out_w <= expected_normalized_w) {
if (WeirdFloatMath.InterpretAsSingle(0x0229C4AB) <
expected_normalized_w) {
if (WeirdFloatMath.C_ZERO < expected_normalized_w) {
var inverse_sqrt_of_expected_normalized_w =
1.0 / Math.Sqrt(expected_normalized_w);
out_w =
(float) (-(inverse_sqrt_of_expected_normalized_w *
inverse_sqrt_of_expected_normalized_w *
expected_normalized_w -
WeirdFloatMath.InterpretAsSingle(0x40400000)) *
WeirdFloatMath.C_3) *
inverse_sqrt_of_expected_normalized_w *
WeirdFloatMath.InterpretAsSingle(0x3F000000));
WeirdFloatMath.C_HALF);
if (out_w <= 0.0) {
out_w = expected_normalized_w;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using fin.data;
using fin.data.dictionaries;
using fin.data.dictionaries;
using fin.schema;
using fin.util.asserts;

Expand Down

0 comments on commit 722de03

Please sign in to comment.