Added ModelEntity.HasTexture, which is true if Texture != null and IsTextured is true. I think this is worth having just because of how many places both comparisons are made in.
Added GeomMath.ExtractRotationSafe extension method, which returns Quaternion.Identity in the scenario that one of the matrix scale components is 0 (which normally results in a NaN Quaternion).
AnimationBatch functions now have a simulate parameter, which skips updating the models MeshBatch if true.
Replaced ModelPreparerExporter.GetModels with GetPreparedRootEntity(..., out models). It's an ugly setup right now, but cloned root entities are needed for animations. And having a method to GetRootEntity and GetModels would be confusing with whether you need to pass the original or prepared root entity to GetModels.
ModelPreparerExporter.AttachLimbs no longer affects the original model.
ModelPreparerExporter now exports tiled textures with dimensions that are powers of two.
Added GeomMath.RoundUpToPower to help get rounded up powers of two.
Added NeedsTexture(model) shorthands to all model exporters. This returns true if ExportTextures option is true, and if model.HasTexture is true.
glTF2 no longer exports TEXCOORD_0 when model is untextered.
glTF2 now exports initial model rotation.
glTF2 now exports initial model WorldMatrix transforms, instead of LocalMatrix transforms.
Changed glTF2 file prefix from obj to gltf.
glTF2 now only computes animation frames once per frame (instead of 3 x models.Count per frame), and now stores the resulting transform components for each model at each frame.
glTF2 bounds calculation now goes off local vertex positions, and also swaps min/max and negates for Y/Z.
glTF2 now restores animation loop mode when done with the animation batch.