File size: 11,614 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
import { Color } from '../math/Color.js';
import { Vector2 } from '../math/Vector2.js';
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';
import { Matrix3 } from '../math/Matrix3.js';
import { Matrix4 } from '../math/Matrix4.js';
import { FileLoader } from './FileLoader.js';
import { Loader } from './Loader.js';
import * as Materials from '../materials/Materials.js';

class MaterialLoader extends Loader {
	constructor(manager) {
		super(manager);
		this.textures = {};
	}

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

		const loader = new FileLoader(scope.manager);
		loader.setPath(scope.path);
		loader.setRequestHeader(scope.requestHeader);
		loader.setWithCredentials(scope.withCredentials);
		loader.load(
			url,
			function (text) {
				try {
					onLoad(scope.parse(JSON.parse(text)));
				} catch (e) {
					if (onError) {
						onError(e);
					} else {
						console.error(e);
					}

					scope.manager.itemError(url);
				}
			},
			onProgress,
			onError
		);
	}

	parse(json) {
		const textures = this.textures;

		function getTexture(name) {
			if (textures[name] === undefined) {
				console.warn('THREE.MaterialLoader: Undefined texture', name);
			}

			return textures[name];
		}

		const material = new Materials[json.type]();

		if (json.uuid !== undefined) material.uuid = json.uuid;
		if (json.name !== undefined) material.name = json.name;
		if (json.color !== undefined && material.color !== undefined) material.color.setHex(json.color);
		if (json.roughness !== undefined) material.roughness = json.roughness;
		if (json.metalness !== undefined) material.metalness = json.metalness;
		if (json.sheen !== undefined) material.sheen = json.sheen;
		if (json.sheenColor !== undefined) material.sheenColor = new Color().setHex(json.sheenColor);
		if (json.sheenRoughness !== undefined) material.sheenRoughness = json.sheenRoughness;
		if (json.emissive !== undefined && material.emissive !== undefined) material.emissive.setHex(json.emissive);
		if (json.specular !== undefined && material.specular !== undefined) material.specular.setHex(json.specular);
		if (json.specularIntensity !== undefined) material.specularIntensity = json.specularIntensity;
		if (json.specularColor !== undefined && material.specularColor !== undefined) material.specularColor.setHex(json.specularColor);
		if (json.shininess !== undefined) material.shininess = json.shininess;
		if (json.clearcoat !== undefined) material.clearcoat = json.clearcoat;
		if (json.clearcoatRoughness !== undefined) material.clearcoatRoughness = json.clearcoatRoughness;
		if (json.transmission !== undefined) material.transmission = json.transmission;
		if (json.thickness !== undefined) material.thickness = json.thickness;
		if (json.attenuationDistance !== undefined) material.attenuationDistance = json.attenuationDistance;
		if (json.attenuationColor !== undefined && material.attenuationColor !== undefined) material.attenuationColor.setHex(json.attenuationColor);
		if (json.fog !== undefined) material.fog = json.fog;
		if (json.flatShading !== undefined) material.flatShading = json.flatShading;
		if (json.blending !== undefined) material.blending = json.blending;
		if (json.combine !== undefined) material.combine = json.combine;
		if (json.side !== undefined) material.side = json.side;
		if (json.shadowSide !== undefined) material.shadowSide = json.shadowSide;
		if (json.opacity !== undefined) material.opacity = json.opacity;
		if (json.transparent !== undefined) material.transparent = json.transparent;
		if (json.alphaTest !== undefined) material.alphaTest = json.alphaTest;
		if (json.depthTest !== undefined) material.depthTest = json.depthTest;
		if (json.depthWrite !== undefined) material.depthWrite = json.depthWrite;
		if (json.colorWrite !== undefined) material.colorWrite = json.colorWrite;
		if (json.alphaWrite !== undefined) material.alphaWrite = json.alphaWrite;

		if (json.stencilWrite !== undefined) material.stencilWrite = json.stencilWrite;
		if (json.stencilWriteMask !== undefined) material.stencilWriteMask = json.stencilWriteMask;
		if (json.stencilFunc !== undefined) material.stencilFunc = json.stencilFunc;
		if (json.stencilRef !== undefined) material.stencilRef = json.stencilRef;
		if (json.stencilFuncMask !== undefined) material.stencilFuncMask = json.stencilFuncMask;
		if (json.stencilFail !== undefined) material.stencilFail = json.stencilFail;
		if (json.stencilZFail !== undefined) material.stencilZFail = json.stencilZFail;
		if (json.stencilZPass !== undefined) material.stencilZPass = json.stencilZPass;

		if (json.wireframe !== undefined) material.wireframe = json.wireframe;
		if (json.wireframeLinewidth !== undefined) material.wireframeLinewidth = json.wireframeLinewidth;
		if (json.wireframeLinecap !== undefined) material.wireframeLinecap = json.wireframeLinecap;
		if (json.wireframeLinejoin !== undefined) material.wireframeLinejoin = json.wireframeLinejoin;

		if (json.rotation !== undefined) material.rotation = json.rotation;

		if (json.linewidth !== 1) material.linewidth = json.linewidth;
		if (json.dashSize !== undefined) material.dashSize = json.dashSize;
		if (json.gapSize !== undefined) material.gapSize = json.gapSize;
		if (json.scale !== undefined) material.scale = json.scale;

		if (json.polygonOffset !== undefined) material.polygonOffset = json.polygonOffset;
		if (json.polygonOffsetFactor !== undefined) material.polygonOffsetFactor = json.polygonOffsetFactor;
		if (json.polygonOffsetUnits !== undefined) material.polygonOffsetUnits = json.polygonOffsetUnits;

		if (json.dithering !== undefined) material.dithering = json.dithering;

		if (json.alphaToCoverage !== undefined) material.alphaToCoverage = json.alphaToCoverage;
		if (json.premultipliedAlpha !== undefined) material.premultipliedAlpha = json.premultipliedAlpha;

		if (json.visible !== undefined) material.visible = json.visible;

		if (json.toneMapped !== undefined) material.toneMapped = json.toneMapped;

		if (json.userData !== undefined) material.userData = json.userData;

		if (json.vertexColors !== undefined) {
			if (typeof json.vertexColors === 'number') {
				material.vertexColors = json.vertexColors > 0 ? true : false;
			} else {
				material.vertexColors = json.vertexColors;
			}
		}

		// Shader Material

		if (json.uniforms !== undefined) {
			for (const name in json.uniforms) {
				const uniform = json.uniforms[name];

				material.uniforms[name] = {};

				switch (uniform.type) {
					case 't':
						material.uniforms[name].value = getTexture(uniform.value);
						break;

					case 'c':
						material.uniforms[name].value = new Color().setHex(uniform.value);
						break;

					case 'v2':
						material.uniforms[name].value = new Vector2().fromArray(uniform.value);
						break;

					case 'v3':
						material.uniforms[name].value = new Vector3().fromArray(uniform.value);
						break;

					case 'v4':
						material.uniforms[name].value = new Vector4().fromArray(uniform.value);
						break;

					case 'm3':
						material.uniforms[name].value = new Matrix3().fromArray(uniform.value);
						break;

					case 'm4':
						material.uniforms[name].value = new Matrix4().fromArray(uniform.value);
						break;

					default:
						material.uniforms[name].value = uniform.value;
				}
			}
		}

		if (json.defines !== undefined) material.defines = json.defines;
		if (json.vertexShader !== undefined) material.vertexShader = json.vertexShader;
		if (json.fragmentShader !== undefined) material.fragmentShader = json.fragmentShader;

		if (json.extensions !== undefined) {
			for (const key in json.extensions) {
				material.extensions[key] = json.extensions[key];
			}
		}

		// Deprecated

		if (json.shading !== undefined) material.flatShading = json.shading === 1; // THREE.FlatShading

		// for PointsMaterial

		if (json.size !== undefined) material.size = json.size;
		if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation;

		// maps

		if (json.map !== undefined) material.map = getTexture(json.map);
		if (json.matcap !== undefined) material.matcap = getTexture(json.matcap);

		if (json.alphaMap !== undefined) material.alphaMap = getTexture(json.alphaMap);

		if (json.bumpMap !== undefined) material.bumpMap = getTexture(json.bumpMap);
		if (json.bumpScale !== undefined) material.bumpScale = json.bumpScale;

		if (json.normalMap !== undefined) material.normalMap = getTexture(json.normalMap);
		if (json.normalMapType !== undefined) material.normalMapType = json.normalMapType;
		if (json.normalScale !== undefined) {
			let normalScale = json.normalScale;

			if (Array.isArray(normalScale) === false) {
				// Blender exporter used to export a scalar. See #7459

				normalScale = [normalScale, normalScale];
			}

			material.normalScale = new Vector2().fromArray(normalScale);
		}

		if (json.displacementMap !== undefined) material.displacementMap = getTexture(json.displacementMap);
		if (json.displacementScale !== undefined) material.displacementScale = json.displacementScale;
		if (json.displacementBias !== undefined) material.displacementBias = json.displacementBias;

		if (json.roughnessMap !== undefined) material.roughnessMap = getTexture(json.roughnessMap);
		if (json.metalnessMap !== undefined) material.metalnessMap = getTexture(json.metalnessMap);

		if (json.emissiveMap !== undefined) material.emissiveMap = getTexture(json.emissiveMap);
		if (json.emissiveIntensity !== undefined) material.emissiveIntensity = json.emissiveIntensity;

		if (json.specularMap !== undefined) material.specularMap = getTexture(json.specularMap);
		if (json.specularIntensityMap !== undefined) material.specularIntensityMap = getTexture(json.specularIntensityMap);
		if (json.specularColorMap !== undefined) material.specularColorMap = getTexture(json.specularColorMap);

		if (json.envMap !== undefined) material.envMap = getTexture(json.envMap);
		if (json.envMapIntensity !== undefined) material.envMapIntensity = json.envMapIntensity;

		if (json.reflectivity !== undefined) material.reflectivity = json.reflectivity;
		if (json.refractionRatio !== undefined) material.refractionRatio = json.refractionRatio;

		if (json.lightMap !== undefined) material.lightMap = getTexture(json.lightMap);
		if (json.lightMapIntensity !== undefined) material.lightMapIntensity = json.lightMapIntensity;

		if (json.aoMap !== undefined) material.aoMap = getTexture(json.aoMap);
		if (json.aoMapIntensity !== undefined) material.aoMapIntensity = json.aoMapIntensity;

		if (json.gradientMap !== undefined) material.gradientMap = getTexture(json.gradientMap);

		if (json.clearcoatMap !== undefined) material.clearcoatMap = getTexture(json.clearcoatMap);
		if (json.clearcoatRoughnessMap !== undefined) material.clearcoatRoughnessMap = getTexture(json.clearcoatRoughnessMap);
		if (json.clearcoatNormalMap !== undefined) material.clearcoatNormalMap = getTexture(json.clearcoatNormalMap);
		if (json.clearcoatNormalScale !== undefined) material.clearcoatNormalScale = new Vector2().fromArray(json.clearcoatNormalScale);

		if (json.transmissionMap !== undefined) material.transmissionMap = getTexture(json.transmissionMap);
		if (json.thicknessMap !== undefined) material.thicknessMap = getTexture(json.thicknessMap);

		if (json.sheenColorMap !== undefined) material.sheenColorMap = getTexture(json.sheenColorMap);
		if (json.sheenRoughnessMap !== undefined) material.sheenRoughnessMap = getTexture(json.sheenRoughnessMap);

		return material;
	}

	setTextures(value) {
		this.textures = value;
		return this;
	}
}

export { MaterialLoader };