Skip to content

Commit 727887f

Browse files
committed
Further code cleanup
1 parent 2f75eb7 commit 727887f

File tree

1 file changed

+34
-93
lines changed

1 file changed

+34
-93
lines changed

Source/RunActivity/Viewer3D/GltfShape.cs

Lines changed: 34 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -701,27 +701,27 @@ void GetBinaryData(GltfShape shape, Gltf gltfFile, string gltfFileName)
701701

702702
var sampler = gltfAnimation.Samplers[gltfChannel.Sampler];
703703
var inputAccessor = gltfFile.Accessors[sampler.Input];
704-
var readInput = GetNormalizedReader(inputAccessor.ComponentType, shape.MsfsFlavoured);
705-
var bri = new BinaryReader(GetBufferView(inputAccessor, out _));
706704
var outputAccessor = gltfFile.Accessors[sampler.Output];
707-
var readOutput = GetNormalizedReader(outputAccessor.ComponentType, shape.MsfsFlavoured);
708-
var bro = new BinaryReader(GetBufferView(outputAccessor, out _));
705+
706+
var inputFloats = new Span<float>(new float[inputAccessor.Count * GetComponentNumber(inputAccessor.Type)]);
707+
Denormalize(inputAccessor, shape.MsfsFlavoured, GetBufferViewSpan(inputAccessor), ref inputFloats);
708+
var outputFloats = new Span<float>(new float[outputAccessor.Count * GetComponentNumber(outputAccessor.Type)]);
709+
Denormalize(outputAccessor, shape.MsfsFlavoured, GetBufferViewSpan(outputAccessor), ref outputFloats);
709710

710711
GltfAnimationChannel channel;
711712
animation.Channels.Add(channel = new GltfAnimationChannel
712713
{
713714
Interpolation = shape.MsfsFlavoured ? AnimationSampler.InterpolationEnum.LINEAR : sampler.Interpolation,
714715
Path = gltfChannel.Target.Path,
715716
TargetNode = gltfChannel.Target.Node,
716-
TimeArray = new float[inputAccessor.Count].Select(_ => readInput(bri)).ToArray(),
717+
TimeArray = inputFloats.ToArray(),
717718
TimeMin = inputAccessor.Min[0],
718719
TimeMax = inputAccessor.Max[0],
719720
OutputQuaternion = gltfChannel.Target.Path == AnimationChannelTarget.PathEnum.rotation ?
720-
new Quaternion[outputAccessor.Count].Select(_ => new Quaternion(readOutput(bro), readOutput(bro), readOutput(bro), readOutput(bro))).ToArray() : null,
721+
MemoryMarshal.Cast<float, Quaternion>(outputFloats).ToArray() : null,
721722
OutputVector3 = gltfChannel.Target.Path == AnimationChannelTarget.PathEnum.scale || gltfChannel.Target.Path == AnimationChannelTarget.PathEnum.translation ?
722-
new Vector3[outputAccessor.Count].Select(_ => new Vector3(readOutput(bro), readOutput(bro), readOutput(bro))).ToArray() : null,
723-
OutputFloats = gltfChannel.Target.Path == AnimationChannelTarget.PathEnum.weights ?
724-
new float[outputAccessor.Count].Select(_ => readOutput(bro)).ToArray() : null,
723+
MemoryMarshal.Cast<float, Vector3>(outputFloats).ToArray() : null,
724+
OutputFloats = gltfChannel.Target.Path == AnimationChannelTarget.PathEnum.weights ? outputFloats.ToArray() : null,
725725
Pointer = gltfChannel.Target.Path == AnimationChannelTarget.PathEnum.pointer ? pointer : null,
726726
});
727727

@@ -742,10 +742,10 @@ void GetBinaryData(GltfShape shape, Gltf gltfFile, string gltfFileName)
742742
switch (PointerTemplates[template])
743743
{
744744
case PointerTypes.FloatVector:
745-
case PointerTypes.Float: channel.OutputFloats = new float[outputAccessor.Count].Select(_ => readOutput(bro)).ToArray(); break;
746-
case PointerTypes.Quaternion: channel.OutputQuaternion = new Quaternion[outputAccessor.Count].Select(_ => new Quaternion(readOutput(bro), readOutput(bro), readOutput(bro), readOutput(bro))).ToArray(); break;
747-
case PointerTypes.Vector3: channel.OutputVector3 = new Vector3[outputAccessor.Count].Select(_ => new Vector3(readOutput(bro), readOutput(bro), readOutput(bro))).ToArray(); break;
748-
case PointerTypes.Vector4: channel.OutputVector4 = new Vector4[outputAccessor.Count].Select(_ => new Vector4(readOutput(bro), readOutput(bro), readOutput(bro), readOutput(bro))).ToArray(); break;
745+
case PointerTypes.Float: channel.OutputFloats = outputFloats.ToArray(); break;
746+
case PointerTypes.Quaternion: channel.OutputQuaternion = MemoryMarshal.Cast<float, Quaternion>(outputFloats).ToArray(); break;
747+
case PointerTypes.Vector3: channel.OutputVector3 = MemoryMarshal.Cast<float, Vector3>(outputFloats).ToArray(); break;
748+
case PointerTypes.Vector4: channel.OutputVector4 = MemoryMarshal.Cast<float, Vector4>(outputFloats).ToArray(); break;
749749
default: break;
750750
}
751751
break;
@@ -872,6 +872,23 @@ bool isMatch(string element, out int matchIndex, out ReadOnlySpan<char> matchPro
872872
}
873873
}
874874

875+
internal static void Denormalize(Accessor accessor, bool msfsFlavoured, Span<byte> bytes, ref Span<float> floats)
876+
{
877+
switch (accessor.ComponentType)
878+
{
879+
case Accessor.ComponentTypeEnum.BYTE: for (var i = 0; i < accessor.Count; i++) floats[i] = Math.Max(bytes[i] / 127f, -1f); break;
880+
case Accessor.ComponentTypeEnum.UNSIGNED_BYTE: for (var i = 0; i < accessor.Count; i++) floats[i] = bytes[i] / 255f; break;
881+
case Accessor.ComponentTypeEnum.UNSIGNED_SHORT: for (var i = 0; i < accessor.Count; i++) floats[i] = MemoryMarshal.Read<ushort>(bytes.Slice(i * sizeof(ushort))) / 65535f; break;
882+
case Accessor.ComponentTypeEnum.SHORT:
883+
// Component type 5122 "SHORT" is a 16 bit int by the glTF specification, but is used as a 16 bit float (half) by asobo-msfs:
884+
for (var i = 0; i < accessor.Count; i++)
885+
floats[i] = msfsFlavoured ? (float)MemoryMarshal.Read<SharpDX.Half>(bytes.Slice(i * sizeof(short))) : Math.Max(MemoryMarshal.Read<short>(bytes.Slice(i * sizeof(short))) / 32767f, -1f);
886+
break;
887+
case Accessor.ComponentTypeEnum.FLOAT:
888+
default: floats = MemoryMarshal.Cast<byte, float>(bytes.Slice(0, floats.Length * sizeof(float))); break;
889+
}
890+
}
891+
875892
internal Span<byte> GetBufferViewSpan(AccessorSparseIndices accessor) => GetBufferViewSpan(accessor?.BufferView, accessor?.ByteOffset ?? 0);
876893
internal Span<byte> GetBufferViewSpan(AccessorSparseValues accessor) => GetBufferViewSpan(accessor?.BufferView, accessor?.ByteOffset ?? 0);
877894
internal Span<byte> GetBufferViewSpan(Accessor accessor) => GetBufferViewSpan(accessor.BufferView, accessor.ByteOffset);
@@ -885,21 +902,6 @@ internal Span<byte> GetBufferViewSpan(int? bufferViewNumber, int accessorByteOff
885902
return bytes.AsSpan(bufferView.ByteOffset + accessorByteOffset);
886903
}
887904

888-
internal Stream GetBufferView(Accessor accessor, out int? byteStride) => GetBufferView(accessor.BufferView, accessor.ByteOffset, out byteStride);
889-
internal Stream GetBufferView(int? bufferViewNumber, int accessorByteOffset, out int? byteStride)
890-
{
891-
byteStride = null;
892-
if (bufferViewNumber == null)
893-
return Stream.Null;
894-
var bufferView = GltfFile.BufferViews[(int)bufferViewNumber];
895-
byteStride = bufferView.ByteStride;
896-
if (!BinaryBuffers.TryGetValue(bufferView.Buffer, out var bytes))
897-
BinaryBuffers.Add(bufferView.Buffer, bytes = glTFLoader.Interface.LoadBinaryBuffer(GltfFile, bufferView.Buffer, GltfFileName));
898-
var stream = new MemoryStream(bytes);
899-
stream.Seek(bufferView.ByteOffset + accessorByteOffset, SeekOrigin.Begin);
900-
return stream;
901-
}
902-
903905
internal int GetSizeInBytes(Accessor accessor)
904906
{
905907
var componentNumber = GetComponentNumber(accessor.Type);
@@ -908,7 +910,7 @@ internal int GetSizeInBytes(Accessor accessor)
908910
return size + padding;
909911
}
910912

911-
int GetComponentNumber(Accessor.TypeEnum type)
913+
internal int GetComponentNumber(Accessor.TypeEnum type)
912914
{
913915
switch (type)
914916
{
@@ -980,59 +982,6 @@ VertexElementFormat GetVertexElementFormat(Accessor accessor, bool msfsFlavoured
980982
}
981983
}
982984

983-
internal static Func<BinaryReader, float> GetNormalizedReader(Accessor.ComponentTypeEnum componentType, bool msfsFlavoured)
984-
{
985-
switch (componentType)
986-
{
987-
case Accessor.ComponentTypeEnum.UNSIGNED_BYTE: return (br) => br.ReadByte() / 255.0f;
988-
case Accessor.ComponentTypeEnum.UNSIGNED_SHORT: return (br) => br.ReadUInt16() / 65535.0f;
989-
case Accessor.ComponentTypeEnum.BYTE: return (br) => Math.Max(br.ReadSByte() / 127.0f, -1.0f);
990-
// Component type 5122 "SHORT" is a 16 bit int by the glTF specification, but is used as a 16 bit float (half) by asobo-msfs:
991-
case Accessor.ComponentTypeEnum.SHORT: return (br) => msfsFlavoured ? ToTwoByteFloat(br.ReadBytes(2)) : Math.Max(br.ReadInt16() / 32767.0f, -1.0f); // the prior is br.ReadHalf() in fact
992-
case Accessor.ComponentTypeEnum.FLOAT:
993-
default: return (br) => br.ReadSingle();
994-
}
995-
}
996-
997-
internal static Func<BinaryReader, ushort> GetIntegerReader(AccessorSparseIndices.ComponentTypeEnum componentType) => GetIntegerReader((Accessor.ComponentTypeEnum)componentType);
998-
internal static Func<BinaryReader, ushort> GetIntegerReader(Accessor.ComponentTypeEnum componentType)
999-
{
1000-
switch (componentType)
1001-
{
1002-
case Accessor.ComponentTypeEnum.BYTE: return (br) => (ushort)br.ReadSByte();
1003-
case Accessor.ComponentTypeEnum.UNSIGNED_INT: return (br) => (ushort)br.ReadUInt32();
1004-
case Accessor.ComponentTypeEnum.UNSIGNED_BYTE: return (br) => br.ReadByte();
1005-
case Accessor.ComponentTypeEnum.UNSIGNED_SHORT:
1006-
default: return (br) => br.ReadUInt16();
1007-
}
1008-
}
1009-
1010-
static float ToTwoByteFloat(byte[] bytes) // Hi, Lo
1011-
{
1012-
var intVal = BitConverter.ToInt32(new byte[] { bytes[0], bytes[1], 0, 0 }, 0);
1013-
1014-
int mant = intVal & 0x03ff;
1015-
int exp = intVal & 0x7c00;
1016-
if (exp == 0x7c00) exp = 0x3fc00;
1017-
else if (exp != 0)
1018-
{
1019-
exp += 0x1c000;
1020-
if (mant == 0 && exp > 0x1c400)
1021-
return BitConverter.ToSingle(BitConverter.GetBytes((intVal & 0x8000) << 16 | exp << 13 | 0x3ff), 0);
1022-
}
1023-
else if (mant != 0)
1024-
{
1025-
exp = 0x1c400;
1026-
do
1027-
{
1028-
mant <<= 1;
1029-
exp -= 0x400;
1030-
} while ((mant & 0x400) == 0);
1031-
mant &= 0x3ff;
1032-
}
1033-
return BitConverter.ToSingle(BitConverter.GetBytes((intVal & 0x8000) << 16 | (exp | mant) << 13), 0);
1034-
}
1035-
1036985
internal static VertexElementUsage GetVertexElementSemantic(string semantic, out int index)
1037986
{
1038987
var split = semantic.Split('_');
@@ -1651,17 +1600,9 @@ public GltfPrimitive(Material material, List<VertexBufferBinding> vertexAttribut
16511600
else
16521601
{
16531602
var accessor = gltfFile.Accessors[(int)skin.InverseBindMatrices];
1654-
InverseBindMatrices = new Matrix[accessor.Count];
1655-
var read = GltfDistanceLevel.GetNormalizedReader(accessor.ComponentType, distanceLevel.Shape.MsfsFlavoured);
1656-
using (var br = new BinaryReader(distanceLevel.GetBufferView(accessor, out _)))
1657-
{
1658-
for (var i = 0; i < InverseBindMatrices.Length; i++)
1659-
InverseBindMatrices[i] = new Matrix(
1660-
read(br), read(br), read(br), read(br),
1661-
read(br), read(br), read(br), read(br),
1662-
read(br), read(br), read(br), read(br),
1663-
read(br), read(br), read(br), read(br));
1664-
}
1603+
Span<float> inputFloats = stackalloc float[accessor.Count * distanceLevel.GetComponentNumber(accessor.Type)];
1604+
GltfDistanceLevel.Denormalize(accessor, distanceLevel.Shape.MsfsFlavoured, distanceLevel.GetBufferViewSpan(accessor), ref inputFloats);
1605+
InverseBindMatrices = MemoryMarshal.Cast<float, Matrix>(inputFloats).ToArray();
16651606
}
16661607
distanceLevel.InverseBindMatrices.Add((int)skin.InverseBindMatrices, InverseBindMatrices);
16671608
}

0 commit comments

Comments
 (0)