File size: 2,640 Bytes
2b7aae2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { LinearFilter } from '../constants.js';
import { FileLoader } from './FileLoader.js';
import { CompressedTexture } from '../textures/CompressedTexture.js';
import { Loader } from './Loader.js';

/**
 * Abstract Base class to block based textures loader (dds, pvr, ...)
 *
 * Sub classes have to implement the parse() method which will be used in load().
 */

class CompressedTextureLoader extends Loader {
	constructor(manager) {
		super(manager);
	}

	load(url, onLoad, onProgress, onError) {
		const scope = this;

		const images = [];

		const texture = new CompressedTexture();

		const loader = new FileLoader(this.manager);
		loader.setPath(this.path);
		loader.setResponseType('arraybuffer');
		loader.setRequestHeader(this.requestHeader);
		loader.setWithCredentials(scope.withCredentials);

		let loaded = 0;

		function loadTexture(i) {
			loader.load(
				url[i],
				function (buffer) {
					const texDatas = scope.parse(buffer, true);

					images[i] = {
						width: texDatas.width,
						height: texDatas.height,
						format: texDatas.format,
						mipmaps: texDatas.mipmaps,
					};

					loaded += 1;

					if (loaded === 6) {
						if (texDatas.mipmapCount === 1) texture.minFilter = LinearFilter;

						texture.image = images;
						texture.format = texDatas.format;
						texture.needsUpdate = true;

						if (onLoad) onLoad(texture);
					}
				},
				onProgress,
				onError
			);
		}

		if (Array.isArray(url)) {
			for (let i = 0, il = url.length; i < il; ++i) {
				loadTexture(i);
			}
		} else {
			// compressed cubemap texture stored in a single DDS file

			loader.load(
				url,
				function (buffer) {
					const texDatas = scope.parse(buffer, true);

					if (texDatas.isCubemap) {
						const faces = texDatas.mipmaps.length / texDatas.mipmapCount;

						for (let f = 0; f < faces; f++) {
							images[f] = { mipmaps: [] };

							for (let i = 0; i < texDatas.mipmapCount; i++) {
								images[f].mipmaps.push(texDatas.mipmaps[f * texDatas.mipmapCount + i]);
								images[f].format = texDatas.format;
								images[f].width = texDatas.width;
								images[f].height = texDatas.height;
							}
						}

						texture.image = images;
					} else {
						texture.image.width = texDatas.width;
						texture.image.height = texDatas.height;
						texture.mipmaps = texDatas.mipmaps;
					}

					if (texDatas.mipmapCount === 1) {
						texture.minFilter = LinearFilter;
					}

					texture.format = texDatas.format;
					texture.needsUpdate = true;

					if (onLoad) onLoad(texture);
				},
				onProgress,
				onError
			);
		}

		return texture;
	}
}

export { CompressedTextureLoader };