-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy paththree-texture-loader-browser.ts
107 lines (96 loc) · 3.94 KB
/
three-texture-loader-browser.ts
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
/*
* VPDB - Virtual Pinball Database
* Copyright (C) 2019 freezy <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { DataTexture, RGBAFormat, Texture as ThreeTexture, TextureLoader, UnsignedByteType } from '../../refs.node';
import { ITextureLoader } from '../irender-api';
import { RGBELoader } from './vendor/RGBELoader';
const imageMap: { [key: string]: string } = {
bumperbase: require('../../../res/maps/bumperbase.png'),
bumperCap: require('../../../res/maps/bumperCap.png'),
bumperring: require('../../../res/maps/bumperring.png'),
bumperskirt: require('../../../res/maps/bumperskirt.png'),
kickerCup: require('../../../res/maps/kickerCup.png'),
kickerGottlieb: require('../../../res/maps/kickerGottlieb.png'),
kickerHoleWood: require('../../../res/maps/kickerHoleWood.png'),
kickerT1: require('../../../res/maps/kickerT1.png'),
kickerWilliams: require('../../../res/maps/kickerWilliams.png'),
ball: require('../../../res/maps/ball.png'),
};
export class ThreeTextureLoaderBrowser implements ITextureLoader<ThreeTexture> {
public async loadDefaultTexture(name: string, ext: string, fileName: string): Promise<ThreeTexture> {
const key = fileName.substr(0, fileName.lastIndexOf('.'));
if (!imageMap[key]) {
throw new Error('Unknown local texture "' + key + '".');
}
return new TextureLoader().load(imageMap[key]);
}
public async loadRawTexture(name: string, data: Buffer, width: number, height: number): Promise<ThreeTexture> {
const texture = new DataTexture(data, width, height, RGBAFormat);
texture.flipY = true;
texture.needsUpdate = true;
return texture;
}
public async loadTexture(name: string, ext: string, data: Buffer): Promise<ThreeTexture> {
const mimeType = getMimeType(data, ext);
if (!mimeType) {
throw new Error('Unknown image format for texture "' + name + '".');
}
const objectUrl = URL.createObjectURL(new Blob([data.buffer], {type: mimeType}));
const texture = await load(mimeType, objectUrl);
texture.name = `texture:${name}`;
texture.needsUpdate = true;
texture.anisotropy = 4;
return texture;
}
}
function getMimeType(data: Buffer, ext: string): string | null {
const header = data.readUInt16BE(0);
switch (header) {
case 0x8950: return 'image/png';
case 0x4749: return 'image/gif';
case 0x424d: return 'image/bmp';
case 0xffd8: return 'image/jpg';
default: switch (ext) {
case '.hdr': return 'application/octet-stream';
case '.exr': return 'image/aces';
default: return null;
}
}
}
async function load(mimeType: string, objectUrl: string): Promise<ThreeTexture> {
if (mimeType === 'application/octet-stream') {
return loadHdrTexture(objectUrl);
}
return loadLdrTexture(objectUrl);
}
async function loadLdrTexture(objectUrl: string): Promise<ThreeTexture> {
return new Promise((resolve, reject) => {
const texture = new ThreeTexture();
texture.image = new Image();
texture.image.addEventListener('load', () => resolve(texture));
texture.image.addEventListener('error', reject);
texture.image.src = objectUrl;
});
}
async function loadHdrTexture(objectUrl: string): Promise<ThreeTexture> {
return new Promise((resolve, reject) => {
new RGBELoader()
.setDataType(UnsignedByteType) // alt: FloatType, HalfFloatType
.load(objectUrl, texture => resolve(texture), undefined, reject);
});
}