@@ -2,51 +2,61 @@ import {
2
2
AmbientLight ,
3
3
AssetPromise ,
4
4
AssetType ,
5
+ ContentRestorer ,
5
6
DiffuseMode ,
6
- Loader ,
7
+ Engine ,
7
8
LoadItem ,
8
- resourceLoader ,
9
+ Loader ,
10
+ RequestConfig ,
9
11
ResourceManager ,
10
12
TextureCube ,
11
13
TextureCubeFace ,
12
- TextureFilterMode
14
+ TextureFilterMode ,
15
+ request ,
16
+ resourceLoader
13
17
} from "@galacean/engine-core" ;
14
18
import { SphericalHarmonics3 } from "@galacean/engine-math" ;
15
19
16
20
@resourceLoader ( AssetType . Env , [ "env" ] )
17
21
class EnvLoader extends Loader < AmbientLight > {
22
+ /**
23
+ * @internal
24
+ */
25
+ static _setTextureByBuffer ( engine : Engine , buffer : ArrayBuffer , texture ?: TextureCube ) {
26
+ const shByteLength = 27 * 4 ;
27
+ const size = new Uint16Array ( buffer , shByteLength , 1 ) ?. [ 0 ] ;
28
+ texture ||= new TextureCube ( engine , size ) ;
29
+ texture . filterMode = TextureFilterMode . Trilinear ;
30
+ const mipmapCount = texture . mipmapCount ;
31
+ let offset = shByteLength + 2 ;
32
+
33
+ for ( let mipLevel = 0 ; mipLevel < mipmapCount ; mipLevel ++ ) {
34
+ const mipSize = size >> mipLevel ;
35
+
36
+ for ( let face = 0 ; face < 6 ; face ++ ) {
37
+ const dataSize = mipSize * mipSize * 4 ;
38
+ const data = new Uint8Array ( buffer , offset , dataSize ) ;
39
+ offset += dataSize ;
40
+ texture . setPixelBuffer ( TextureCubeFace . PositiveX + face , data , mipLevel ) ;
41
+ }
42
+ }
43
+ return texture ;
44
+ }
45
+
18
46
load ( item : LoadItem , resourceManager : ResourceManager ) : AssetPromise < AmbientLight > {
19
47
return new AssetPromise ( ( resolve , reject ) => {
48
+ const requestConfig = { ...item , type : "arraybuffer" } as RequestConfig ;
49
+ const engine = resourceManager . engine ;
20
50
resourceManager
21
51
// @ts -ignore
22
- . _request < ArrayBuffer > ( item . url , { ... item , type : "arraybuffer" } )
52
+ . _request < ArrayBuffer > ( item . url , requestConfig )
23
53
. then ( ( arraybuffer ) => {
24
- const shArray = new Float32Array ( arraybuffer , 0 , 27 ) ;
25
- const shByteLength = 27 * 4 ;
26
- const size = new Uint16Array ( arraybuffer , shByteLength , 1 ) ?. [ 0 ] ;
27
-
28
- const { engine } = resourceManager ;
29
- const texture = new TextureCube ( engine , size ) ;
30
- texture . filterMode = TextureFilterMode . Trilinear ;
31
- const mipmapCount = texture . mipmapCount ;
32
- let offset = shByteLength + 2 ;
33
-
34
- for ( let mipLevel = 0 ; mipLevel < mipmapCount ; mipLevel ++ ) {
35
- const mipSize = size >> mipLevel ;
36
-
37
- for ( let face = 0 ; face < 6 ; face ++ ) {
38
- const dataSize = mipSize * mipSize * 4 ;
39
- const data = new Uint8Array ( arraybuffer , offset , dataSize ) ;
40
- offset += dataSize ;
41
- texture . setPixelBuffer ( TextureCubeFace . PositiveX + face , data , mipLevel ) ;
42
- }
43
- }
44
-
54
+ const texture = EnvLoader . _setTextureByBuffer ( engine , arraybuffer ) ;
55
+ engine . resourceManager . addContentRestorer ( new EnvContentRestorer ( texture , item . url , requestConfig ) ) ;
45
56
const ambientLight = new AmbientLight ( engine ) ;
46
57
const sh = new SphericalHarmonics3 ( ) ;
47
-
48
58
ambientLight . diffuseMode = DiffuseMode . SphericalHarmonics ;
49
- sh . copyFromArray ( shArray ) ;
59
+ sh . copyFromArray ( new Float32Array ( arraybuffer , 0 , 27 ) ) ;
50
60
ambientLight . diffuseSphericalHarmonics = sh ;
51
61
ambientLight . specularTexture = texture ;
52
62
ambientLight . specularTextureDecodeRGBM = true ;
@@ -58,3 +68,27 @@ class EnvLoader extends Loader<AmbientLight> {
58
68
} ) ;
59
69
}
60
70
}
71
+
72
+ /**
73
+ * @internal
74
+ */
75
+ class EnvContentRestorer extends ContentRestorer < TextureCube > {
76
+ constructor (
77
+ resource : TextureCube ,
78
+ public url : string ,
79
+ public requestConfig : RequestConfig
80
+ ) {
81
+ super ( resource ) ;
82
+ }
83
+
84
+ override restoreContent ( ) : AssetPromise < TextureCube > {
85
+ return new AssetPromise ( ( resolve , reject ) => {
86
+ request < ArrayBuffer > ( this . url , this . requestConfig )
87
+ . then ( ( buffer ) => {
88
+ EnvLoader . _setTextureByBuffer ( this . resource . engine , buffer , this . resource ) ;
89
+ resolve ( this . resource ) ;
90
+ } )
91
+ . catch ( reject ) ;
92
+ } ) ;
93
+ }
94
+ }
0 commit comments