@@ -1441,7 +1441,8 @@ public GltfPrimitive(Material material, List<VertexBufferBinding> vertexAttribut
14411441 /// Used in case of morphing. Only 8 morph targets can be bound at any time, so need to select the actually active ones.
14421442 /// </summary>
14431443 VertexBufferBinding [ ] ActiveVertexBufferBindings ;
1444- int [ ] ActiveMorphConfig ;
1444+ int [ ] ActiveWeightIndices ;
1445+ float [ ] ActiveWeights ;
14451446
14461447 /// <summary>
14471448 /// Select the max. 8 active morph targets and compile the active buffer binding.
@@ -1452,29 +1453,51 @@ public GltfPrimitive(Material material, List<VertexBufferBinding> vertexAttribut
14521453 if ( MorphWeights . Length <= MaxActiveMorphTargets )
14531454 return ( MorphConfig , MorphWeights ) ;
14541455
1455- // Drop targets with the lowest weights if needed, according to the glTF spec recommendation.
1456- var activeTargets = MorphWeights
1457- . Select ( ( w , i ) => ( w , i ) )
1458- . OrderByDescending ( v => v . w )
1459- . Take ( MaxActiveMorphTargets ) ;
1460-
14611456 ActiveVertexBufferBindings = ActiveVertexBufferBindings ?? VertexBufferBindings . ToArray ( ) ;
14621457 Array . Resize ( ref ActiveVertexBufferBindings , 16 ) ; // This is what the vs_4_0 can handle.
1463- ActiveMorphConfig = ActiveMorphConfig ?? MorphConfig . ToArray ( ) ;
1464- ActiveMorphConfig [ 7 ] = activeTargets . Count ( ) ;
1458+ ActiveWeightIndices = ActiveWeightIndices ?? new int [ RenderProcess . MAX_MORPH_BUFFERS ] ;
1459+ ActiveWeights = ActiveWeights ?? new float [ RenderProcess . MAX_MORPH_BUFFERS ] ;
14651460
1466- // Recompile the buffer binding
1467- for ( var i = 0 ; i < activeTargets . Count ( ) ; i ++ )
1461+ // First select the weight indices
1462+ var w = 0 ;
1463+ for ( var i = 0 ; i < MorphWeights . Length ; i ++ )
1464+ {
1465+ if ( MorphWeights [ i ] == 0 )
1466+ continue ;
1467+ if ( w < MaxActiveMorphTargets )
1468+ {
1469+ ActiveWeightIndices [ w ++ ] = i ;
1470+ }
1471+ else
1472+ {
1473+ // Drop targets with the lowest weights if needed, according to the glTF spec recommendation.
1474+ var smallestWeight = 0 ;
1475+ for ( var j = 0 ; j < MaxActiveMorphTargets ; j ++ )
1476+ {
1477+ if ( MorphWeights [ ActiveWeightIndices [ j ] ] < MorphWeights [ ActiveWeightIndices [ smallestWeight ] ] )
1478+ smallestWeight = j ;
1479+ }
1480+ if ( MorphWeights [ i ] > MorphWeights [ ActiveWeightIndices [ smallestWeight ] ] )
1481+ ActiveWeightIndices [ smallestWeight ] = i ;
1482+ }
1483+ }
1484+ MorphConfig [ 7 ] = w ;
1485+
1486+ // Recompile the buffer binding and the weights from the indices
1487+ for ( var i = 0 ; i < w ; i ++ )
1488+ {
14681489 for ( var j = 0 ; j < MorphConfig [ 8 ] ; j ++ )
1469- ActiveVertexBufferBindings [ 8 + MorphConfig [ 8 ] * i + j ] = VertexBufferBindings [ 8 + MorphConfig [ 8 ] * activeTargets . ElementAt ( i ) . i + j ] ;
1490+ ActiveVertexBufferBindings [ 8 + MorphConfig [ 8 ] * i + j ] = VertexBufferBindings [ 8 + MorphConfig [ 8 ] * ActiveWeightIndices [ i ] + j ] ;
1491+ ActiveWeights [ i ] = MorphWeights [ ActiveWeightIndices [ i ] ] ;
1492+ }
14701493 // Fill up the rest of ActiveVertexBufferBindings with anything.
1471- for ( var i = 8 + MorphConfig [ 8 ] * activeTargets . Count ( ) ; i < 16 ; i ++ )
1494+ for ( var i = 8 + MorphConfig [ 8 ] * w ; i < 16 ; i ++ )
14721495 ActiveVertexBufferBindings [ i ] = VertexBufferBindings [ 8 ] ;
14731496
1474- return ( ActiveMorphConfig , activeTargets . Select ( v => v . w ) . ToArray ( ) ) ;
1497+ return ( MorphConfig , ActiveWeights ) ;
14751498 }
14761499
1477- public bool HasMorphTargets ( ) => MorphConfig [ 7 ] > 0 ;
1500+ public bool HasMorphTargets ( ) => MorphWeights . Length > 0 ;
14781501
14791502 public override void Draw ( GraphicsDevice graphicsDevice )
14801503 {
0 commit comments