Skip to content

Commit

Permalink
Refactor positioning, write basic test
Browse files Browse the repository at this point in the history
  • Loading branch information
henbagle committed Dec 3, 2023
1 parent 16d365e commit 9c0c155
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 63 deletions.
24 changes: 24 additions & 0 deletions ME3Tweaks.Wwiser.Tests/HierarchyTests/PositioningTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using ME3Tweaks.Wwiser.Model.ParameterNode.Positioning;

namespace ME3Tweaks.Wwiser.Tests.HierarchyTests;

public class PositioningTests
{
[TestCase]
public void PositioningParams_V134_Parses()
{
var byteData = new byte[] { 0x03, 0x0A };
var version = 134;
var (_, result) = TestHelpers.Deserialize<PositioningChunk>(byteData, version);
Assert.Multiple(() =>
{
Assert.That(result.HasPositioning, Is.True);
Assert.That(result.Has3DPositioning, Is.True);

Assert.That(result.PositioningBits.Value, Is.EqualTo(BitsPositioning.BitsPositioningInner.PositioningInfoOverrideParent | BitsPositioning.BitsPositioningInner.HasListenerRelativeRouting));
Assert.That(result.PositioningBits.PanningType, Is.EqualTo(BitsPositioning.SpeakerPanningType.DirectSpeakerAssignment));
Assert.That(result.PositioningBits.PositionType, Is.EqualTo(BitsPositioning.PositionType3D.Emitter));
});

}
}
58 changes: 34 additions & 24 deletions ME3Tweaks.Wwiser/Model/ParameterNode/Positioning/BitsPositioning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

namespace ME3Tweaks.Wwiser.Model.ParameterNode.Positioning;

public class BitsPositioning : IBinarySerializable
public class BitsPositioning
{
[Ignore]
public BitsPositioningInner Value { get; set; }

public void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
[Ignore]
public SpeakerPanningType PanningType { get; set; }

[Ignore]
public PositionType3D PositionType { get; set; }

public void Serialize(Stream stream, PositioningChunk parent, uint version)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
var parent = serializationContext.FindAncestor<PositioningChunk>();

// Apply the two bool properties in case their values have changed since deserialization.
if (parent.HasPositioning)
{
Expand All @@ -32,26 +35,27 @@ public void Serialize(Stream stream, Endianness endianness, BinarySerializationC
write &= BitsPositioningInner.Unknown2D2;
}

stream.WriteByte((byte)write);
stream.WriteByte((byte)((byte)write & ((byte)PanningType << 2) & ((byte)PositionType) << 5));
}

public void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
public void Deserialize(Stream stream, PositioningChunk parent, uint version)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
var parent = serializationContext.FindAncestor<PositioningChunk>();
var read = (BitsPositioningInner)(byte)stream.ReadByte();

var read = (byte)stream.ReadByte();
var bits = (BitsPositioningInner)read;

// Is3DPositioningAvailable is bit 3 on this version
if (version is > 112 and <= 122 && read.HasFlag(BitsPositioningInner.Unknown2D2))
if (version is > 112 and <= 122 && bits.HasFlag(BitsPositioningInner.Unknown2D2))
{
read &= BitsPositioningInner.Is3DPositioningAvailable;
read &= ~BitsPositioningInner.Unknown2D2;
bits &= BitsPositioningInner.Is3DPositioningAvailable;
bits &= ~BitsPositioningInner.Unknown2D2;
}

Value = read;
Value = bits;
PanningType = (SpeakerPanningType)(read >> 2);
PositionType = (PositionType3D)(read >> 5);

// Set this bool so we can reference it later
parent.HasPositioning = read.HasFlag(BitsPositioningInner.PositioningInfoOverrideParent);
parent.HasPositioning = bits.HasFlag(BitsPositioningInner.PositioningInfoOverrideParent);

// Also this one
if (version > 129) parent.Has3DPositioning = Value.HasFlag(BitsPositioningInner.HasListenerRelativeRouting);
Expand All @@ -68,15 +72,21 @@ public enum BitsPositioningInner : byte
Unknown3D1 = 1 << 5,
Unknown3D2 = 1 << 6,
Unknown3D3 = 1 << 7,

//AkSpeakerPanningType v132>
}

[Flags]
public enum SpeakerPanningType : byte
{
DirectSpeakerAssignment = 0b0000_0000,
BalanceFadeHeight = 0b0000_0100,
SteeringPanner = 0b0000_1000,

//Ak3DPositionType v120>
BalanceFadeHeight = 0b0000_0001,
SteeringPanner = 0b0000_0010,
}

[Flags]
public enum PositionType3D : byte
{
Emitter = 0b0000_0000,
EmitterWithAutomation = 0b0010_0000,
ListenerWithAutomation = 0b0100_0000,
EmitterWithAutomation = 0b0000_0001,
ListenerWithAutomation = 0b0000_0010,
}
}
31 changes: 10 additions & 21 deletions ME3Tweaks.Wwiser/Model/ParameterNode/Positioning/Gen3DParams.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,8 @@

namespace ME3Tweaks.Wwiser.Model.ParameterNode.Positioning;

public class Gen3DParams : IBinarySerializable
public class Gen3DParams
{
[Ignore]
public bool HasAutomation { get; set; }

[Ignore]
public bool HasDynamic { get; set; }

[Ignore]
public PositioningType Type { get; set; }

Expand All @@ -22,12 +16,9 @@ public class Gen3DParams : IBinarySerializable
[Ignore]
public bool IsSpatialized { get; set; }

public void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
public void Serialize(Stream stream, PositioningChunk parent, uint version)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
var parent = serializationContext.FindAncestor<PositioningChunk>();

SetPropertiesFromBools(version);
SetPropertiesFromBools(parent, version);

if (version <= 89)
{
Expand Down Expand Up @@ -61,10 +52,8 @@ public void Serialize(Stream stream, Endianness endianness, BinarySerializationC
if (version <= 89) stream.WriteBoolByte(IsSpatialized);
}

public void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
public void Deserialize(Stream stream, PositioningChunk parent, uint version)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
var parent = serializationContext.FindAncestor<PositioningChunk>();
var reader = new BinaryReader(stream);

if (version <= 89)
Expand Down Expand Up @@ -95,14 +84,14 @@ public void Deserialize(Stream stream, Endianness endianness, BinarySerializatio
if (version <= 129) AttenuationId = reader.ReadUInt32();
if (version <= 89) IsSpatialized = reader.ReadBoolean();

SetBoolsFromProperties(version);
SetBoolsFromProperties(parent, version);
}

/// <summary>
/// Correctly sets the properties based on version and
/// the HasAutomation and HasDynamic flags
/// </summary>
private void SetPropertiesFromBools(uint version)
private void SetPropertiesFromBools(PositioningChunk parent, uint version)
{
// TODO: Crossversion - this will need to be implemented
}
Expand All @@ -111,10 +100,10 @@ private void SetPropertiesFromBools(uint version)
/// Correctly sets the HasAutomation and HasDynamic flags based on the
/// other properties in the class
/// </summary>
private void SetBoolsFromProperties(uint version)
private void SetBoolsFromProperties(PositioningChunk parent, uint version)
{
// Todo: rewrite so bitwise operators use IsFlag - more readable
HasAutomation = version switch
parent.HasAutomation = version switch
{
<= 72 => Type is PositioningType.UserDef3D,
<= 89 => Type is not PositioningType.Positioning2D,
Expand All @@ -124,10 +113,10 @@ private void SetBoolsFromProperties(uint version)
_ => (((byte)Mode >> 5 ) & 3) != 1,
};

HasDynamic = version switch
parent.HasDynamic = version switch
{
<= 72 => Type is PositioningType.GameDef3D,
<= 89 => !HasAutomation,
<= 89 => !parent.HasDynamic,
_ => false
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

namespace ME3Tweaks.Wwiser.Model.ParameterNode.Positioning;
// This class has a lot of logic based on prior data,
// so basically all the serialized properties use custom serialization
// so all the serialized properties are dropped out of serialization framework
// and depend on the [Ignore] bools in this class

public class PositioningChunk
public class PositioningChunk : IBinarySerializable
{
[Ignore]
[Ignore]
public bool HasPositioning { get; set; }

[Ignore]
Expand All @@ -19,14 +19,40 @@ public class PositioningChunk
[Ignore]
public bool HasPanner { get; set; }

[FieldOrder(0)]
public BitsPositioning PositioningBits { get; set; }
[Ignore]
public bool HasAutomation { get; set; }

[Ignore]
public bool HasDynamic { get; set; }

[Ignore]
public BitsPositioning PositioningBits { get; set; } = new();

[FieldOrder(1)]
public PositioningFlags PositioningFlags { get; set; }
[Ignore]
public PositioningFlags PositioningFlags { get; set; } = new();

[FieldOrder(2)]
[SerializeWhen(nameof(Has3DPositioning), true)]
public Gen3DParams Gen3DParams { get; set; }

[Ignore]
public Gen3DParams Gen3DParams { get; set; } = new();

public void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
PositioningBits.Serialize(stream, this, version);
PositioningFlags.Serialize(stream, this, version);
if (Has3DPositioning)
{
Gen3DParams.Serialize(stream, this, version);
}
}

public void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
PositioningBits.Deserialize(stream, this, version);
PositioningFlags.Deserialize(stream, this, version);
if (Has3DPositioning)
{
Gen3DParams.Deserialize(stream, this, version);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace ME3Tweaks.Wwiser.Model.ParameterNode.Positioning;

public class PositioningFlags : IBinarySerializable
public class PositioningFlags
{
[Ignore]
public int CenterPct { get; set; }
Expand All @@ -13,10 +13,8 @@ public class PositioningFlags : IBinarySerializable
[Ignore]
public float PanFR { get; set; }

public void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
public void Serialize(Stream stream, PositioningChunk parent, uint version)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
var parent = serializationContext.FindAncestor<PositioningChunk>();
if (parent.HasPositioning)
{
if (version <= 56)
Expand All @@ -39,10 +37,8 @@ public void Serialize(Stream stream, Endianness endianness, BinarySerializationC
}
}

public void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
public void Deserialize(Stream stream, PositioningChunk parent, uint version)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
var parent = serializationContext.FindAncestor<PositioningChunk>();
var reader = new BinaryReader(stream);

if (parent.HasPositioning)
Expand Down

0 comments on commit 9c0c155

Please sign in to comment.