Skip to content

Commit b8e95f2

Browse files
authored
fix byte alignment for byte and short models (KhronosGroup#390)
* fix byte align for byte and short models * removing extra lines of white space * using numbers instead of sizeof for computing alignment
1 parent e365e1a commit b8e95f2

7 files changed

+50
-47
lines changed
Binary file not shown.

Output/Mesh_PrimitiveAttribute/Mesh_PrimitiveAttribute_01.gltf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"buffers": [
4444
{
4545
"uri": "Mesh_PrimitiveAttribute_01.bin",
46-
"byteLength": 80
46+
"byteLength": 88
4747
}
4848
],
4949
"bufferViews": [
@@ -55,12 +55,13 @@
5555
{
5656
"buffer": 0,
5757
"byteOffset": 48,
58-
"byteLength": 8,
58+
"byteLength": 16,
59+
"byteStride": 4,
5960
"name": "Texture Coords 0"
6061
},
6162
{
6263
"buffer": 0,
63-
"byteOffset": 56,
64+
"byteOffset": 64,
6465
"byteLength": 24,
6566
"name": "Indices"
6667
}
Binary file not shown.

Output/Mesh_PrimitiveVertexColor/Mesh_PrimitiveVertexColor_01.gltf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"buffers": [
4444
{
4545
"uri": "Mesh_PrimitiveVertexColor_01.bin",
46-
"byteLength": 84
46+
"byteLength": 88
4747
}
4848
],
4949
"bufferViews": [
@@ -55,12 +55,13 @@
5555
{
5656
"buffer": 0,
5757
"byteOffset": 48,
58-
"byteLength": 12,
58+
"byteLength": 16,
59+
"byteStride": 4,
5960
"name": "Colors"
6061
},
6162
{
6263
"buffer": 0,
63-
"byteOffset": 60,
64+
"byteOffset": 64,
6465
"byteLength": 24,
6566
"name": "Indices"
6667
}
Binary file not shown.

Output/Mesh_PrimitiveVertexColor/Mesh_PrimitiveVertexColor_02.gltf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"buffers": [
4444
{
4545
"uri": "Mesh_PrimitiveVertexColor_02.bin",
46-
"byteLength": 96
46+
"byteLength": 104
4747
}
4848
],
4949
"bufferViews": [
@@ -55,12 +55,13 @@
5555
{
5656
"buffer": 0,
5757
"byteOffset": 48,
58-
"byteLength": 24,
58+
"byteLength": 32,
59+
"byteStride": 8,
5960
"name": "Colors"
6061
},
6162
{
6263
"buffer": 0,
63-
"byteOffset": 72,
64+
"byteOffset": 80,
6465
"byteLength": 24,
6566
"name": "Indices"
6667
}

Source/Runtime/GLTFConverter.cs

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ namespace AssetGenerator.Runtime
1414
/// </summary>
1515
internal class GLTFConverter
1616
{
17-
private static List<glTFLoader.Schema.Buffer> Buffers { get; set; }
18-
private static List<glTFLoader.Schema.BufferView> BufferViews { get; set; }
19-
private static List<glTFLoader.Schema.Accessor> Accessors { get; set; }
20-
private static List<glTFLoader.Schema.Material> Materials { get; set; }
21-
private static List<glTFLoader.Schema.Node> Nodes { get; set; }
17+
private static List<glTFLoader.Schema.Buffer> Buffers { get; set; }
18+
private static List<glTFLoader.Schema.BufferView> BufferViews { get; set; }
19+
private static List<glTFLoader.Schema.Accessor> Accessors { get; set; }
20+
private static List<glTFLoader.Schema.Material> Materials { get; set; }
21+
private static List<glTFLoader.Schema.Node> Nodes { get; set; }
2222
private static List<glTFLoader.Schema.Scene> Scenes { get; set; }
23-
private static List<glTFLoader.Schema.Image> Images { get; set; }
24-
private static List<glTFLoader.Schema.Sampler> Samplers { get; set; }
25-
private static List<glTFLoader.Schema.Texture> Textures { get; set; }
23+
private static List<glTFLoader.Schema.Image> Images { get; set; }
24+
private static List<glTFLoader.Schema.Sampler> Samplers { get; set; }
25+
private static List<glTFLoader.Schema.Texture> Textures { get; set; }
2626
private static List<glTFLoader.Schema.Mesh> Meshes { get; set; }
2727

2828
/// <summary>
@@ -49,7 +49,7 @@ private static void initBuffers()
4949
Samplers = new List<glTFLoader.Schema.Sampler>();
5050
Textures = new List<glTFLoader.Schema.Texture>();
5151
Meshes = new List<glTFLoader.Schema.Mesh>();
52-
}
52+
}
5353

5454
/// <summary>
5555
/// Converts Runtime GLTF to Schema GLTF object.
@@ -482,7 +482,7 @@ private static int ConvertNodeToSchema(Runtime.Node runtimeNode, Runtime.GLTF gl
482482
{
483483
node.Translation = runtimeNode.Translation.Value.ToArray();
484484
}
485-
485+
486486
if (runtimeNode.Children != null)
487487
{
488488
var childrenIndices = new List<int>();
@@ -779,7 +779,7 @@ private static glTFLoader.Schema.Material ConvertMaterialToSchema(Runtime.Materi
779779
default:
780780
throw new NotImplementedException("Extension schema conversion not implemented for " + extension.Name);
781781
}
782-
782+
783783
if (gltf.ExtensionsUsed == null)
784784
{
785785
gltf.ExtensionsUsed = new List<string>(new[] { extension.Name });
@@ -1008,7 +1008,6 @@ private static Dictionary<string, int> InterleaveMeshPrimitiveAttributes(Runtime
10081008
}
10091009
if (meshPrimitive.Colors != null)
10101010
{
1011-
10121011
// if not multiple of 4, add padding
10131012
totalByteLength = Align(geometryData, totalByteLength, 4);
10141013
int colorOffset = totalByteLength;
@@ -1044,7 +1043,7 @@ private static Dictionary<string, int> InterleaveMeshPrimitiveAttributes(Runtime
10441043
break;
10451044
default:
10461045
throw new NotImplementedException("Color component type " + meshPrimitive.ColorComponentType + " not supported!");
1047-
1046+
10481047
}
10491048
var colorAccessor = CreateAccessor(bufferviewIndex, colorOffset, colorAccessorComponentType, count, "Color Accessor", null, null, vectorType, normalized);
10501049
Accessors.Add(colorAccessor);
@@ -1054,7 +1053,7 @@ private static Dictionary<string, int> InterleaveMeshPrimitiveAttributes(Runtime
10541053
}
10551054
// if not multiple of 4, add padding
10561055
totalByteLength = Align(geometryData, totalByteLength, 4);
1057-
1056+
10581057
if (i == 0)
10591058
{
10601059
bufferView.ByteStride = totalByteLength;
@@ -1070,36 +1069,34 @@ private static int WriteTextureCoords(MeshPrimitive meshPrimitive, List<Vector2>
10701069
{
10711070
int byteLength = 0;
10721071
int offset = (int)geometryData.Writer.BaseStream.Position;
1073-
1072+
10741073
int count = max - min + 1;
10751074
Vector2[] tcs = textureCoordSet.ToArray();
1075+
byteLength = 8 * count;
10761076
switch (meshPrimitive.TextureCoordsComponentType)
10771077
{
10781078
case MeshPrimitive.TextureCoordsComponentTypeEnum.FLOAT:
1079-
byteLength = sizeof(float) * 2 * count;
10801079
for (int i = min; i <= max; ++i)
10811080
{
10821081
geometryData.Writer.Write(tcs[i]);
10831082
}
10841083
break;
10851084
case MeshPrimitive.TextureCoordsComponentTypeEnum.NORMALIZED_UBYTE:
1086-
byteLength = sizeof(byte) * 2 * count;
10871085
for (int i = min; i <= max; ++i)
10881086
{
10891087
geometryData.Writer.Write(Convert.ToByte(Math.Round(tcs[i].X * byte.MaxValue)));
10901088
geometryData.Writer.Write(Convert.ToByte(Math.Round(tcs[i].Y * byte.MaxValue)));
1089+
Align(geometryData, 2, 4);
10911090
}
10921091
break;
10931092
case MeshPrimitive.TextureCoordsComponentTypeEnum.NORMALIZED_USHORT:
1094-
byteLength = sizeof(ushort) * 2 * count;
10951093
for (int i = min; i <= max; ++i)
10961094
{
1097-
10981095
geometryData.Writer.Write(Convert.ToUInt16(Math.Round(tcs[i].X * ushort.MaxValue)));
10991096
geometryData.Writer.Write(Convert.ToUInt16(Math.Round(tcs[i].Y * ushort.MaxValue)));
11001097
}
11011098
break;
1102-
default:
1099+
default:
11031100
throw new NotImplementedException("Byte length calculation not implemented for TextureCoordsComponentType: " + meshPrimitive.TextureCoordsComponentType);
11041101
}
11051102
byteLength = (int)geometryData.Writer.BaseStream.Position - offset;
@@ -1112,26 +1109,24 @@ private static int WriteColors(MeshPrimitive meshPrimitive, int min, int max, Da
11121109
int byteLength = 0;
11131110
int count = max - min + 1;
11141111
int vectorSize = meshPrimitive.ColorType == MeshPrimitive.ColorTypeEnum.VEC3 ? 3 : 4;
1112+
byteLength = 0;
11151113

11161114
switch (meshPrimitive.ColorComponentType)
11171115
{
11181116
case MeshPrimitive.ColorComponentTypeEnum.NORMALIZED_UBYTE:
1119-
byteLength = sizeof(byte) * vectorSize * count;
1120-
11211117
for (int i = min; i <= max; ++i)
11221118
{
11231119
geometryData.Writer.Write(Convert.ToByte(Math.Round(meshPrimitive.Colors[i].X * byte.MaxValue)));
11241120
geometryData.Writer.Write(Convert.ToByte(Math.Round(meshPrimitive.Colors[i].Y * byte.MaxValue)));
11251121
geometryData.Writer.Write(Convert.ToByte(Math.Round(meshPrimitive.Colors[i].Z * byte.MaxValue)));
1126-
if (meshPrimitive.ColorType == MeshPrimitive.ColorTypeEnum.VEC4)
1122+
if (meshPrimitive.ColorType == MeshPrimitive.ColorTypeEnum.VEC4)
11271123
{
11281124
geometryData.Writer.Write(Convert.ToByte(Math.Round(meshPrimitive.Colors[i].W * byte.MaxValue)));
11291125
}
1126+
byteLength += Align(geometryData, vectorSize, 4);
11301127
}
11311128
break;
11321129
case MeshPrimitive.ColorComponentTypeEnum.NORMALIZED_USHORT:
1133-
byteLength = sizeof(ushort) * vectorSize * count;
1134-
11351130
for (int i = min; i <= max; ++i)
11361131
{
11371132
geometryData.Writer.Write(Convert.ToUInt16(Math.Round(meshPrimitive.Colors[i].X * ushort.MaxValue)));
@@ -1142,11 +1137,10 @@ private static int WriteColors(MeshPrimitive meshPrimitive, int min, int max, Da
11421137
{
11431138
geometryData.Writer.Write(Convert.ToUInt16(Math.Round(meshPrimitive.Colors[i].W * ushort.MaxValue)));
11441139
}
1140+
byteLength += Align(geometryData, 2 * vectorSize, 4);
11451141
}
11461142
break;
11471143
case MeshPrimitive.ColorComponentTypeEnum.FLOAT:
1148-
byteLength = sizeof(float) * vectorSize * count;
1149-
11501144
for (int i = min; i <= max; ++i)
11511145
{
11521146
geometryData.Writer.Write(meshPrimitive.Colors[i].X);
@@ -1157,6 +1151,7 @@ private static int WriteColors(MeshPrimitive meshPrimitive, int min, int max, Da
11571151
{
11581152
geometryData.Writer.Write(meshPrimitive.Colors[i].W);
11591153
}
1154+
byteLength += Align(geometryData, 4 * vectorSize, 4);
11601155
}
11611156
break;
11621157
}
@@ -1248,28 +1243,34 @@ private static glTFLoader.Schema.MeshPrimitive ConvertMeshPrimitiveToSchema(Runt
12481243
var colorAccessorComponentType = glTFLoader.Schema.Accessor.ComponentTypeEnum.FLOAT;
12491244
var colorAccessorType = runtimeMeshPrimitive.ColorType == MeshPrimitive.ColorTypeEnum.VEC3 ? glTFLoader.Schema.Accessor.TypeEnum.VEC3 : glTFLoader.Schema.Accessor.TypeEnum.VEC4;
12501245
int vectorSize = runtimeMeshPrimitive.ColorType == MeshPrimitive.ColorTypeEnum.VEC3 ? 3 : 4;
1251-
int byteLength = 0;
12521246

12531247
// Create BufferView
12541248
int byteOffset = (int)geometryData.Writer.BaseStream.Position;
1255-
byteLength = WriteColors(runtimeMeshPrimitive, 0, runtimeMeshPrimitive.Colors.Count() - 1, geometryData);
12561249

1250+
int byteLength = WriteColors(runtimeMeshPrimitive, 0, runtimeMeshPrimitive.Colors.Count() - 1, geometryData);
1251+
int? byteStride = null;
12571252
switch (runtimeMeshPrimitive.ColorComponentType)
12581253
{
12591254
case MeshPrimitive.ColorComponentTypeEnum.NORMALIZED_UBYTE:
12601255
colorAccessorComponentType = glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_BYTE;
1261-
byteLength = sizeof(byte) * vectorSize * runtimeMeshPrimitive.Colors.Count();
1256+
if (vectorSize == 3)
1257+
{
1258+
byteStride = 4;
1259+
}
12621260
break;
12631261
case MeshPrimitive.ColorComponentTypeEnum.NORMALIZED_USHORT:
12641262
colorAccessorComponentType = glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_SHORT;
1265-
byteLength = sizeof(ushort) * vectorSize * runtimeMeshPrimitive.Colors.Count();
1263+
if (vectorSize == 3)
1264+
{
1265+
byteStride = 8;
1266+
}
12661267
break;
12671268
default: //Default to ColorComponentTypeEnum.FLOAT:
12681269
colorAccessorComponentType = glTFLoader.Schema.Accessor.ComponentTypeEnum.FLOAT;
1269-
byteLength = sizeof(float) * vectorSize * runtimeMeshPrimitive.Colors.Count();
12701270
break;
12711271
}
1272-
var bufferView = CreateBufferView(bufferIndex, "Colors", byteLength, byteOffset, null);
1272+
1273+
var bufferView = CreateBufferView(bufferIndex, "Colors", byteLength, byteOffset, byteStride);
12731274
BufferViews.Add(bufferView);
12741275
int bufferviewIndex = BufferViews.Count() - 1;
12751276

@@ -1282,14 +1283,13 @@ private static glTFLoader.Schema.MeshPrimitive ConvertMeshPrimitiveToSchema(Runt
12821283
if (normalized)
12831284
{
12841285
// Pad any additional bytes if byteLength is not a multiple of 4
1285-
Align(geometryData ,byteLength, 4);
1286+
Align(geometryData, byteLength, 4);
12861287
}
12871288
}
12881289
if (runtimeMeshPrimitive.TextureCoordSets != null)
12891290
{
12901291
for (int i = 0; i < runtimeMeshPrimitive.TextureCoordSets.Count; ++i)
12911292
{
1292-
12931293
List<Vector2> textureCoordSet = runtimeMeshPrimitive.TextureCoordSets[i];
12941294
int byteOffset = (int)geometryData.Writer.BaseStream.Position;
12951295
int byteLength = WriteTextureCoords(runtimeMeshPrimitive, textureCoordSet, 0, runtimeMeshPrimitive.TextureCoordSets[i].Count() - 1, geometryData);
@@ -1298,13 +1298,15 @@ private static glTFLoader.Schema.MeshPrimitive ConvertMeshPrimitiveToSchema(Runt
12981298
glTFLoader.Schema.Accessor.ComponentTypeEnum accessorComponentType;
12991299
// we normalize only if the texture cood accessor type is not float
13001300
bool normalized = runtimeMeshPrimitive.TextureCoordsComponentType != MeshPrimitive.TextureCoordsComponentTypeEnum.FLOAT;
1301+
int? byteStride = null;
13011302
switch (runtimeMeshPrimitive.TextureCoordsComponentType)
13021303
{
13031304
case MeshPrimitive.TextureCoordsComponentTypeEnum.FLOAT:
13041305
accessorComponentType = glTFLoader.Schema.Accessor.ComponentTypeEnum.FLOAT;
13051306
break;
13061307
case MeshPrimitive.TextureCoordsComponentTypeEnum.NORMALIZED_UBYTE:
13071308
accessorComponentType = glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_BYTE;
1309+
byteStride = 4;
13081310
break;
13091311
case MeshPrimitive.TextureCoordsComponentTypeEnum.NORMALIZED_USHORT:
13101312
accessorComponentType = glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_SHORT;
@@ -1314,7 +1316,7 @@ private static glTFLoader.Schema.MeshPrimitive ConvertMeshPrimitiveToSchema(Runt
13141316
break;
13151317
}
13161318

1317-
var bufferView = CreateBufferView(bufferIndex, "Texture Coords " + i, byteLength, byteOffset, null);
1319+
var bufferView = CreateBufferView(bufferIndex, "Texture Coords " + i, byteLength, byteOffset, byteStride);
13181320
BufferViews.Add(bufferView);
13191321
int bufferviewIndex = BufferViews.Count() - 1;
13201322
// Create Accessor
@@ -1388,8 +1390,6 @@ private static glTFLoader.Schema.MeshPrimitive ConvertMeshPrimitiveToSchema(Runt
13881390

13891391
mPrimitive.Indices = Accessors.Count() - 1;
13901392
}
1391-
1392-
13931393

13941394
mPrimitive.Attributes = attributes;
13951395
if (runtimeMeshPrimitive.Material != null)

0 commit comments

Comments
 (0)