Closed MonoLogueChi closed 7 months ago
I solved the problem temporarily, but I think it is a bug and it should be automatic line wrapping that is correct
public class Matrix4x4Formatter : IYamlFormatter<Matrix4x4>
{
public static readonly Matrix4x4Formatter Instance = new();
public void Serialize(ref Utf8YamlEmitter emitter, Matrix4x4 value, YamlSerializationContext context)
{
var fs = new[]
{
new[] { value.m00, value.m10, value.m20, value.m30 },
new[] { value.m01, value.m11, value.m21, value.m31 },
new[] { value.m02, value.m12, value.m22, value.m32 },
new[] { value.m03, value.m13, value.m23, value.m33 }
};
emitter.BeginSequence();
emitter.WriteRaw(ReadOnlySpan<byte>.Empty, false, true);
foreach (var f in fs) Utils.WriteFloatArrayWithFlowStyle(ref emitter, f, context);
emitter.EndSequence();
}
public Matrix4x4 Deserialize(ref YamlParser parser, YamlDeserializationContext context)
{
if (parser.IsNullScalar())
{
parser.Read();
return default;
}
var formatter = context.Resolver.GetFormatterWithVerify<List<Vector4>>();
var list = context.DeserializeWithAlias(formatter, ref parser);
if (list.Count == 4) return new Matrix4x4(list[0], list[1], list[2], list[3]);
return default;
}
}
public static void WriteFloatArrayWithFlowStyle(ref Utf8YamlEmitter emitter, IEnumerable<float> value,
YamlSerializationContext context)
{
emitter.BeginSequence(SequenceStyle.Flow);
foreach (var f in value) emitter.WriteFloat(f);
emitter.EndSequence();
}
Thanks for the report. I'll fix this later.
My relevant code is at VYaml.UnityResolvers, you can use Matrix4x4
or List<Vector3>
for testing
@hadashiA
I have done some testing and the following code temporarily solves the issue, but it may not be completely correct. I hope this can be helpful.
case EmitState.BlockSequenceEntry:
{
switch (PreviousState)
{
case EmitState.BlockMappingValue:
if (IsFirstElement) WriteRaw1(YamlCodes.Lf);
break;
case EmitState.BlockSequenceEntry:
if (!IsFirstElement)
for (int i = 0; i < options.IndentWidth; i++)
WriteRaw1(YamlCodes.Space);
break;
}
var output = writer.GetSpan(currentIndentLevel * options.IndentWidth + BlockSequenceEntryHeader.Length + 1);
var offset = 0;
WriteIndent(output, ref offset);
BlockSequenceEntryHeader.CopyTo(output[offset..]);
offset += BlockSequenceEntryHeader.Length;
output[offset++] = YamlCodes.FlowSequenceStart;
writer.Advance(offset);
break;
}
@hadashiA There is another issue when serializing structures like List<float[][]>, you will get the following result:
- -[1, 0, 0, 0]
-[1, 0, 0, 0]
-[1, 0, 0, 0]
-[1, 0, 0, 0]
- -[1, 0, 0, 0]
-[1, 0, 0, 0]
-[1, 0, 0, 0]
-[1, 0, 0, 0]
@MonoLogueChi Thanks for the report. I believe I fixed your test case in #93. I'll probably release it as soon as I have a few more validations.
Thanks,My test is normal
output
Matrix4x4:
-
- [-7.782528, 37.35536, -47.91584, 0]
- [43.59058, 42.45243, -28.33409, 0]
- [37.03134, -86.71092, -3.385229, 0]
- [12.82171, 1.237767, -83.08399, 0]
-
- [2.874351, -47.73241, -64.72952, 0]
- [34.91239, -64.36443, -55.1876, 0]
- [65.48726, -39.25167, -24.1115, 0]
- [28.50582, 6.619106, -85.29636, 0]
output
RectOffset:
- [97, 93, 94, 30]
- [8, 47, 91, 2]
I encountered some problems when implementing Matrix4x4Formatter. I would like to ask how to implement it.
First I implemented Vector4Formatter
Then implement Matrix4x4Formatter based on this
But the YAML string obtained is similar to this
As a result, it is impossible to deserialize