@@ -362,7 +362,9 @@ public void UpdateResultMatrices()
362362 int hIndex = Hierarchy [ i ] ;
363363
364364 // Transform the matrix repeatedly for all of its parents
365- while ( hIndex > - 1 && hIndex < Hierarchy . Length )
365+ int depth = 0 ;
366+
367+ while ( hIndex > - 1 && hIndex < Hierarchy . Length && depth < 32 )
366368 {
367369 // Can finish calculating sooner if we already have the result matrix for the next level up
368370 if ( resultCalculated [ hIndex ] )
@@ -379,6 +381,8 @@ public void UpdateResultMatrices()
379381 else
380382 break ;
381383 }
384+
385+ depth ++ ;
382386 }
383387
384388 ResultMatrices [ i ] = res ;
@@ -2160,9 +2164,14 @@ void LoadContent()
21602164
21612165 if ( ! found )
21622166 Trace . TraceWarning ( "Shape descriptor file {0} specifies texture {1} to be replaced, " +
2163- "but shape {2} does not contain this texture." , ( filePath + "d" ) , tex , filePath ) ;
2167+ "but shape {2} does not contain this texture." , DescriptorPath , tex , filePath ) ;
21642168 }
21652169
2170+ int [ ] modifiedHierarchy = null ;
2171+ // Prepare to consider hierarchy changes
2172+ if ( sdFile . shape . ESD_MatrixParent . Count > 0 )
2173+ modifiedHierarchy = ( int [ ] ) sFile . shape . lod_controls ? . FirstOrDefault ( ) ? . distance_levels ? . FirstOrDefault ( ) ? . distance_level_header . hierarchy . Clone ( ) ;
2174+
21662175 // Manipulate matrices as defined in the sd file
21672176 foreach ( string matName in sdFile . shape . ESD_ModifiedMatrices )
21682177 {
@@ -2210,10 +2219,32 @@ void LoadContent()
22102219 sFile . shape . matrices [ i ] = MSTSMatrixFromXNA ( newMatrix , sFile . shape . matrices [ i ] . Name ) ;
22112220 }
22122221
2213- // Finally, see if this matrix is to be renamed
2214- if ( sdFile . shape . ESD_MatrixRename . TryGetValue ( matName , out string newName ) )
2222+ // See if this matrix should have its parent changed
2223+ if ( sdFile . shape . ESD_MatrixParent . TryGetValue ( matName , out string newParent ) )
22152224 {
2216- sFile . shape . matrices [ i ] . Name = newName ;
2225+ int thisIndex = i ;
2226+ int parentIndex = - 1 ;
2227+
2228+ for ( int m = 0 ; m < sFile . shape . matrices . Count ; m ++ )
2229+ {
2230+ if ( sFile . shape . matrices [ m ] . Name . ToUpper ( ) == newParent . ToUpper ( ) )
2231+ {
2232+ parentIndex = m ;
2233+ break ;
2234+ }
2235+ }
2236+
2237+ // Found the new parent matrix, update the temporary hierarchy list accordingly
2238+ if ( parentIndex >= 0 )
2239+ {
2240+ if ( modifiedHierarchy != null && thisIndex >= 0 && thisIndex < modifiedHierarchy . Length )
2241+ modifiedHierarchy [ thisIndex ] = parentIndex ;
2242+ }
2243+ else // Couldn't find new parent matrix
2244+ {
2245+ Trace . TraceWarning ( "Shape descriptor file {0} specifies matrix name {1} to be utilized, " +
2246+ "but shape {2} does not contain this matrix." , DescriptorPath , newParent , filePath ) ;
2247+ }
22172248 }
22182249
22192250 found = true ;
@@ -2222,7 +2253,68 @@ void LoadContent()
22222253
22232254 if ( ! found )
22242255 Trace . TraceWarning ( "Shape descriptor file {0} specifies matrix name {1} to be modified, " +
2225- "but shape {2} does not contain this matrix." , ( filePath + "d" ) , matName , filePath ) ;
2256+ "but shape {2} does not contain this matrix." , DescriptorPath , matName , filePath ) ;
2257+ }
2258+
2259+ // Check that hierarchy changes make sense, then apply to shape file
2260+ if ( modifiedHierarchy != null && sdFile . shape . ESD_MatrixParent . Count > 0 )
2261+ {
2262+ // Iterate through every hierarchy element to make sure it resolves back to the main object
2263+ // If anything in the modified hierarchy fails, do not update the shape hierarchy
2264+ bool valid = false ;
2265+
2266+ for ( int hIndex = 0 ; hIndex < modifiedHierarchy . Length ; hIndex ++ )
2267+ {
2268+ int nextIndex = modifiedHierarchy [ hIndex ] ;
2269+ int depth = 0 ;
2270+
2271+ while ( nextIndex > - 1 && nextIndex < modifiedHierarchy . Length && depth < 32 )
2272+ {
2273+ if ( nextIndex == hIndex )
2274+ break ; // We have reached an infinite loop
2275+ nextIndex = modifiedHierarchy [ nextIndex ] ;
2276+
2277+ depth ++ ;
2278+ }
2279+
2280+ // The above calculation should produce a final index of -1
2281+ // This means the hierarchy could be traced back to the main shape
2282+ if ( nextIndex == - 1 )
2283+ valid = true ;
2284+ else
2285+ break ;
2286+ }
2287+
2288+ if ( valid )
2289+ {
2290+ foreach ( lod_control lodControl in sFile . shape . lod_controls )
2291+ {
2292+ foreach ( distance_level distanceLevel in lodControl . distance_levels )
2293+ {
2294+ // Note: This assumes the hierarchy is the same for every LOD...is this always true?
2295+ distanceLevel . distance_level_header . hierarchy = modifiedHierarchy ;
2296+ }
2297+ }
2298+ }
2299+ else
2300+ {
2301+ Trace . TraceWarning ( "Hierarchy changes specified in shape descriptor file {0} " +
2302+ "produce an invalid hierarchy when applied to shape {1}, hierarchy has not been updated." , DescriptorPath , filePath ) ;
2303+ }
2304+ }
2305+
2306+ // Guarantee that matrix renaming happens after all other operations
2307+ foreach ( KeyValuePair < string , string > renamePair in sdFile . shape . ESD_MatrixRename )
2308+ {
2309+ for ( int i = 0 ; i < sFile . shape . matrices . Count ; i ++ )
2310+ {
2311+ // Check if this matrix is to be renamed, and rename accordingly
2312+ // Ignore case
2313+ if ( sFile . shape . matrices [ i ] . Name . ToUpper ( ) == renamePair . Key . ToUpper ( ) )
2314+ {
2315+ sFile . shape . matrices [ i ] . Name = renamePair . Value ;
2316+ }
2317+ }
22262318 }
22272319
22282320 // Manipulate LOD settings as defined in the sd file
@@ -2234,10 +2326,10 @@ void LoadContent()
22342326 {
22352327 lodControl . distance_levels [ lodIndex . Key ] . distance_level_header . dlevel_selection = lodIndex . Value ;
22362328 }
2237- else // LOD index defined doesn't eist
2329+ else // LOD index defined doesn't exist
22382330 {
22392331 Trace . TraceWarning ( "Shape descriptor file {0} specifies LOD index {1} to be modified, " +
2240- "but shape {2} does not have this many LODs." , ( filePath + "d" ) , lodIndex . Key , filePath ) ;
2332+ "but shape {2} does not have this many LODs." , DescriptorPath , lodIndex . Key , filePath ) ;
22412333 }
22422334 }
22432335 }
0 commit comments