@@ -572,12 +572,14 @@ void GetBinaryData(GltfShape shape, Gltf gltfFile, string gltfFileName)
572572 GetVertexElementFormat ( gltfFile . Accessors [ attributes . Current . Value ] , shape . MsfsFlavoured ) ,
573573 GetVertexElementSemantic ( attributes . Current . Key , out var index ) , index ) ) ;
574574 Accessors . Add ( attributes . Current . Value ) ;
575- if ( Debugger . IsAttached ) DebugName += string . Join ( ":" , attributes . Current . Key , Path . GetFileNameWithoutExtension ( gltfFileName ) ) ;
575+ if ( Debugger . IsAttached ) DebugName = ( DebugName != "" ? DebugName + "," : "" ) + attributes . Current . Key ;
576576 }
577577 loop = attributes . MoveNext ( ) ;
578578 }
579579 while ( loop && gltfFile . Accessors [ attributes . Current . Value ] . ByteOffset < previousOffset + byteStride ) ;
580580
581+ if ( Debugger . IsAttached ) DebugName += ":" + Path . GetFileNameWithoutExtension ( gltfFileName ) ;
582+
581583 if ( Accessors . All ( a => VertexBufferBindings . ContainsKey ( a ) ) )
582584 continue ;
583585
@@ -1165,8 +1167,8 @@ public GltfSubObject(MeshPrimitive meshPrimitive, string name, int hierarchyInde
11651167 var vertexAttributes = meshPrimitive . Attributes . SelectMany ( a => distanceLevel . VertexBufferBindings . Where ( kvp => kvp . Key == a . Value ) . Select ( kvp => kvp . Value ) ) . ToList ( ) ;
11661168 var vertexCount = vertexAttributes . FirstOrDefault ( ) . VertexBuffer ? . VertexCount ?? 0 ;
11671169
1168- // Currently three PBR vertex input combinations are possible. Any model must use either of those.
1169- // If a vertex attribute buffer is missing to match one of the three, a dummy one must be added.
1170+ // Currently the below PBR vertex input combinations are possible. Any model must use one of those pipelines .
1171+ // If vertex attribute buffer(s) are missing to match one of these, dummy one(s) must be added.
11701172 // The order of the vertex buffers is unimportant, the shader will attach by semantics.
11711173 // If more combinations to be added in the future, there must be support for them both in SceneryShader and ShadowMapShader.
11721174 //
@@ -1197,7 +1199,7 @@ public GltfSubObject(MeshPrimitive meshPrimitive, string name, int hierarchyInde
11971199 }
11981200
11991201 // Cannot proceed without Normal at all, must add a dummy one.
1200- if ( ! meshPrimitive . Attributes . TryGetValue ( "NORMAL" , out var accessorNormals ) )
1202+ if ( ! meshPrimitive . Attributes . ContainsKey ( "NORMAL" ) )
12011203 {
12021204 vertexAttributes . Add ( new VertexBufferBinding ( new VertexBuffer ( shape . Viewer . GraphicsDevice ,
12031205 new VertexDeclaration ( new VertexElement ( 0 , VertexElementFormat . Color , VertexElementUsage . Normal , 0 ) ) , vertexCount , BufferUsage . None ) { Name = "NORMAL_DUMMY" } ) ) ;
@@ -1207,7 +1209,7 @@ public GltfSubObject(MeshPrimitive meshPrimitive, string name, int hierarchyInde
12071209 options |= SceneryMaterialOptions . PbrHasNormals ;
12081210
12091211 // Cannot proceed without TexCoord_0 at all, must add a dummy one.
1210- if ( ! meshPrimitive . Attributes . TryGetValue ( "TEXCOORD_0" , out var accessorTexcoords ) )
1212+ if ( ! meshPrimitive . Attributes . ContainsKey ( "TEXCOORD_0" ) )
12111213 {
12121214 vertexAttributes . Add ( new VertexBufferBinding ( new VertexBuffer ( shape . Viewer . GraphicsDevice ,
12131215 new VertexDeclaration ( new VertexElement ( 0 , VertexElementFormat . NormalizedShort2 , VertexElementUsage . TextureCoordinate , 0 ) ) , vertexCount , BufferUsage . None ) { Name = "TEXCOORD_0_DUMMY" } ) ) ;
@@ -1232,10 +1234,15 @@ public GltfSubObject(MeshPrimitive meshPrimitive, string name, int hierarchyInde
12321234 // Per-pixel tangent calculation gives better result. In that case we are not using the provided Tangent vertex attribute at all, so it can be removed. (See BoomBox)
12331235 if ( TangentsAlwaysCalculatedPerPixel )
12341236 {
1235- var removables = vertexAttributes . Where ( b => b . VertexBuffer . VertexDeclaration . GetVertexElements ( ) . Any ( e => e . VertexElementUsage == VertexElementUsage . Tangent ) ) ;
1237+ var removables = vertexAttributes . Where ( b => {
1238+ var ve = b . VertexBuffer . VertexDeclaration . GetVertexElements ( ) ;
1239+ return ve . Count ( ) == 1 && ve . Any ( e => e . VertexElementUsage == VertexElementUsage . Tangent ) ;
1240+ } ) ;
12361241 foreach ( var r in removables )
12371242 Disposables . Enqueue ( r . VertexBuffer ) ;
1238- vertexAttributes . RemoveAll ( b => removables . Contains ( b ) ) ;
1243+ if ( vertexAttributes . RemoveAll ( b => removables . Contains ( b ) ) == 0 )
1244+ // Unsuccessful removal because the buffers are interleaved
1245+ options |= SceneryMaterialOptions . PbrHasTangents ;
12391246 }
12401247 else
12411248 options |= SceneryMaterialOptions . PbrHasTangents ;
@@ -1356,6 +1363,7 @@ public class GltfPrimitive : ShapePrimitive
13561363 {
13571364 public readonly int [ ] Joints ; // Replaces ShapePrimitive.HierarchyIndex for non-skinned primitives
13581365 public readonly Matrix [ ] InverseBindMatrices ;
1366+ static readonly Matrix [ ] UnskinnedInverseBindMatrix = new [ ] { Matrix . Identity } ;
13591367
13601368 /// <summary>
13611369 /// It is used in <see cref="SetRenderMatrices"/> to store the animated bones until uploading them to GPU.
@@ -1427,7 +1435,7 @@ public GltfPrimitive(Material material, List<VertexBufferBinding> vertexAttribut
14271435 {
14281436 // Non-skinned model
14291437 Joints = new [ ] { HierarchyIndex } ;
1430- InverseBindMatrices = new [ ] { Matrix . Identity } ;
1438+ InverseBindMatrices = UnskinnedInverseBindMatrix ;
14311439 }
14321440 else
14331441 {
@@ -1518,7 +1526,7 @@ public GltfPrimitive(Material material, List<VertexBufferBinding> vertexAttribut
15181526 ActiveVertexBufferBindings [ 8 + MorphConfig [ 8 ] * i + j ] = VertexBufferBindings [ 8 + MorphConfig [ 8 ] * ActiveWeightIndices [ i ] + j ] ;
15191527 ActiveWeights [ i ] = MorphWeights [ ActiveWeightIndices [ i ] ] ;
15201528 }
1521- // Fill up the rest of ActiveVertexBufferBindings with anything.
1529+ // Fill up the rest of ActiveVertexBufferBindings with anything, as a padding .
15221530 for ( var i = 8 + MorphConfig [ 8 ] * w ; i < 16 ; i ++ )
15231531 ActiveVertexBufferBindings [ i ] = VertexBufferBindings [ 8 ] ;
15241532
@@ -1726,12 +1734,7 @@ public void Animate(int animationNumber, float time, Matrix[] animatedMatrices)
17261734 Quaternion . Normalize ( Quaternion . Multiply ( v1 , A ( t ) ) + Quaternion . Multiply ( b1 , B ( t ) ) + Quaternion . Multiply ( v2 , C ( t ) ) + Quaternion . Multiply ( a2 , D ( t ) ) ) ;
17271735
17281736 /// <summary>
1729- /// It is used to store the adjustments needed for the Khronos sample models for being able to show them all at once in a single consist.
1730- /// For this to work 'git clone https://github.com/KhronosGroup/glTF-Sample-Models.git' to the MSTS/TRAINS/TRAINSET folder, so that the
1731- /// models will be available in e.g. MSTS/TRAINS/TRAINSET/glTF-Sample-Models/2.0/... folder. Then start like:
1732- /// RunActivity.exe -start -explorer "C:\Devel\MSTS\ROUTES\USA2\PATHS\tut6path.pat" "glTF-Sample-Models" 12:00 1 0
1733- /// RunActivity.exe -start -explorer "C:\Devel\MSTS\ROUTES\USA2\PATHS\tut6path.pat" "glTF-Sample-Models&AnimatedTriangle" 12:00 1 0
1734- /// RunActivity.exe -start -explorer "C:\Devel\MSTS\ROUTES\USA2\PATHS\tut6path.pat" "glTF-Sample-Models#2" 12:00 1 0
1737+ /// Adjustments needed for the Khronos sample assets models.
17351738 /// </summary>
17361739 static readonly Dictionary < string , Matrix > SampleModelsAdjustments = new Dictionary < string , Matrix >
17371740 {
0 commit comments