@@ -84,6 +84,10 @@ import { GetMappingForKey } from "./Extensions/objectModelMapping";
84
84
import { deepMerge } from "core/Misc/deepMerger" ;
85
85
import { GetTypedArrayConstructor } from "core/Buffers/bufferUtils" ;
86
86
87
+ // Caching these dynamic imports gives a surprising perf boost (compared to importing them directly each time).
88
+ let AnimationGroupModulePromise : Nullable < Promise < typeof import ( "core/Animations/animationGroup" ) > > = null ;
89
+ let LoaderAnimationPromise : Nullable < Promise < typeof import ( "./glTFLoaderAnimation" ) > > = null ;
90
+
87
91
export { GLTFFileLoader } ;
88
92
89
93
interface ILoaderProperty extends IProperty {
@@ -1615,6 +1619,8 @@ export class GLTFLoader implements IGLTFLoader {
1615
1619
}
1616
1620
1617
1621
private _loadAnimationsAsync ( ) : Promise < void > {
1622
+ this . _parent . _startPerformanceCounter ( "Load animations" ) ;
1623
+
1618
1624
const animations = this . _gltf . animations ;
1619
1625
if ( ! animations ) {
1620
1626
return Promise . resolve ( ) ;
@@ -1634,7 +1640,9 @@ export class GLTFLoader implements IGLTFLoader {
1634
1640
) ;
1635
1641
}
1636
1642
1637
- return Promise . all ( promises ) . then ( ( ) => { } ) ;
1643
+ return Promise . all ( promises ) . then ( ( ) => {
1644
+ this . _parent . _endPerformanceCounter ( "Load animations" ) ;
1645
+ } ) ;
1638
1646
}
1639
1647
1640
1648
/**
@@ -1644,13 +1652,19 @@ export class GLTFLoader implements IGLTFLoader {
1644
1652
* @returns A promise that resolves with the loaded Babylon animation group when the load is complete
1645
1653
*/
1646
1654
public loadAnimationAsync ( context : string , animation : IAnimation ) : Promise < AnimationGroup > {
1655
+ this . _parent . _startPerformanceCounter ( "Load animation" ) ;
1656
+
1647
1657
const promise = this . _extensionsLoadAnimationAsync ( context , animation ) ;
1648
1658
if ( promise ) {
1649
1659
return promise ;
1650
1660
}
1651
1661
1662
+ if ( ! AnimationGroupModulePromise ) {
1663
+ AnimationGroupModulePromise = import ( "core/Animations/animationGroup" ) ;
1664
+ }
1665
+
1652
1666
// eslint-disable-next-line @typescript-eslint/naming-convention
1653
- return import ( "core/Animations/animationGroup" ) . then ( ( { AnimationGroup } ) => {
1667
+ return AnimationGroupModulePromise . then ( ( { AnimationGroup } ) => {
1654
1668
this . _babylonScene . _blockEntityCollection = ! ! this . _assetContainer ;
1655
1669
const babylonAnimationGroup = new AnimationGroup ( animation . name || `animation${ animation . index } ` , this . _babylonScene ) ;
1656
1670
babylonAnimationGroup . _parentContainer = this . _assetContainer ;
@@ -1672,6 +1686,8 @@ export class GLTFLoader implements IGLTFLoader {
1672
1686
) ;
1673
1687
}
1674
1688
1689
+ this . _parent . _endPerformanceCounter ( "Load animation" ) ;
1690
+
1675
1691
return Promise . all ( promises ) . then ( ( ) => {
1676
1692
babylonAnimationGroup . normalize ( 0 ) ;
1677
1693
return babylonAnimationGroup ;
@@ -1689,7 +1705,7 @@ export class GLTFLoader implements IGLTFLoader {
1689
1705
* @param onLoad Called for each animation loaded
1690
1706
* @returns A void promise that resolves when the load is complete
1691
1707
*/
1692
- public async _loadAnimationChannelAsync (
1708
+ public _loadAnimationChannelAsync (
1693
1709
context : string ,
1694
1710
animationContext : string ,
1695
1711
animation : IAnimation ,
@@ -1698,11 +1714,11 @@ export class GLTFLoader implements IGLTFLoader {
1698
1714
) : Promise < void > {
1699
1715
const promise = this . _extensionsLoadAnimationChannelAsync ( context , animationContext , animation , channel , onLoad ) ;
1700
1716
if ( promise ) {
1701
- return await promise ;
1717
+ return promise ;
1702
1718
}
1703
1719
1704
1720
if ( channel . target . node == undefined ) {
1705
- return await Promise . resolve ( ) ;
1721
+ return Promise . resolve ( ) ;
1706
1722
}
1707
1723
1708
1724
const targetNode = ArrayItem . Get ( `${ context } /target/node` , this . _gltf . nodes , channel . target . node ) ;
@@ -1711,49 +1727,54 @@ export class GLTFLoader implements IGLTFLoader {
1711
1727
1712
1728
// Ignore animations that have no animation targets.
1713
1729
if ( ( pathIsWeights && ! targetNode . _numMorphTargets ) || ( ! pathIsWeights && ! targetNode . _babylonTransformNode ) ) {
1714
- return await Promise . resolve ( ) ;
1730
+ return Promise . resolve ( ) ;
1715
1731
}
1716
1732
1717
1733
// Don't load node animations if disabled.
1718
1734
if ( ! this . _parent . loadNodeAnimations && ! pathIsWeights && ! targetNode . _isJoint ) {
1719
- return await Promise . resolve ( ) ;
1735
+ return Promise . resolve ( ) ;
1720
1736
}
1721
- // async-load the animation sampler to provide the interpolation of the channelTargetPath
1722
- await import ( "./glTFLoaderAnimation" ) ;
1723
1737
1724
- let properties : IInterpolationPropertyInfo [ ] ;
1725
- switch ( channelTargetPath ) {
1726
- case AnimationChannelTargetPath . TRANSLATION : {
1727
- properties = GetMappingForKey ( "/nodes/{}/translation" ) ?. interpolation ! ;
1728
- break ;
1729
- }
1730
- case AnimationChannelTargetPath . ROTATION : {
1731
- properties = GetMappingForKey ( "/nodes/{}/rotation" ) ?. interpolation ! ;
1732
- break ;
1733
- }
1734
- case AnimationChannelTargetPath . SCALE : {
1735
- properties = GetMappingForKey ( "/nodes/{}/scale" ) ?. interpolation ! ;
1736
- break ;
1737
- }
1738
- case AnimationChannelTargetPath . WEIGHTS : {
1739
- properties = GetMappingForKey ( "/nodes/{}/weights" ) ?. interpolation ! ;
1740
- break ;
1738
+ if ( ! LoaderAnimationPromise ) {
1739
+ LoaderAnimationPromise = import ( "./glTFLoaderAnimation" ) ;
1740
+ }
1741
+
1742
+ // async-load the animation sampler to provide the interpolation of the channelTargetPath
1743
+ return LoaderAnimationPromise . then ( ( ) => {
1744
+ let properties : IInterpolationPropertyInfo [ ] ;
1745
+ switch ( channelTargetPath ) {
1746
+ case AnimationChannelTargetPath . TRANSLATION : {
1747
+ properties = GetMappingForKey ( "/nodes/{}/translation" ) ?. interpolation ! ;
1748
+ break ;
1749
+ }
1750
+ case AnimationChannelTargetPath . ROTATION : {
1751
+ properties = GetMappingForKey ( "/nodes/{}/rotation" ) ?. interpolation ! ;
1752
+ break ;
1753
+ }
1754
+ case AnimationChannelTargetPath . SCALE : {
1755
+ properties = GetMappingForKey ( "/nodes/{}/scale" ) ?. interpolation ! ;
1756
+ break ;
1757
+ }
1758
+ case AnimationChannelTargetPath . WEIGHTS : {
1759
+ properties = GetMappingForKey ( "/nodes/{}/weights" ) ?. interpolation ! ;
1760
+ break ;
1761
+ }
1762
+ default : {
1763
+ throw new Error ( `${ context } /target/path: Invalid value (${ channel . target . path } )` ) ;
1764
+ }
1741
1765
}
1742
- default : {
1743
- throw new Error ( `${ context } /target/path: Invalid value (${ channel . target . path } )` ) ;
1766
+ // stay safe
1767
+ if ( ! properties ) {
1768
+ throw new Error ( `${ context } /target/path: Could not find interpolation properties for target path (${ channel . target . path } )` ) ;
1744
1769
}
1745
- }
1746
- // stay safe
1747
- if ( ! properties ) {
1748
- throw new Error ( `${ context } /target/path: Could not find interpolation properties for target path (${ channel . target . path } )` ) ;
1749
- }
1750
1770
1751
- const targetInfo : IObjectInfo < IInterpolationPropertyInfo [ ] > = {
1752
- object : targetNode ,
1753
- info : properties ,
1754
- } ;
1771
+ const targetInfo : IObjectInfo < IInterpolationPropertyInfo [ ] > = {
1772
+ object : targetNode ,
1773
+ info : properties ,
1774
+ } ;
1755
1775
1756
- return await this . _loadAnimationChannelFromTargetInfoAsync ( context , animationContext , animation , channel , targetInfo , onLoad ) ;
1776
+ return this . _loadAnimationChannelFromTargetInfoAsync ( context , animationContext , animation , channel , targetInfo , onLoad ) ;
1777
+ } ) ;
1757
1778
}
1758
1779
1759
1780
/**
0 commit comments