-
Notifications
You must be signed in to change notification settings - Fork 0
/
model.js
84 lines (75 loc) · 2.62 KB
/
model.js
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
(function() {
class Model {
get nFaces() {
return this.f.length;
}
constructor(file, textures) {
this.file = file;
this.textures = textures;
this.v = []; // Vertexes
this.f = []; // Faces
this.vt = []; //
this.vn = []; // Normal vector for each vertex
}
load() {
const steps = [
this._loadObj(),
...Object.keys(this.textures).map((type) => this._loadTexture(type, this.textures[type]))
];
return Promise.all(steps);
}
_loadTexture(type, file) {
return (new TGAImage(file)).load().then((img) => {
this.textures[type] = img;
});
}
_loadObj() {
return fetch(this.file)
.then((res) => res.text())
.then((data) => {
data.split('\n')
.forEach((l) => {
const [item, ...rest] = l.split(' ');
switch (item) {
case 'v':
this.v.push(rest.map(Number));
break;
case 'f':
this.f.push(rest.map((i) => {
return i.split('/').map((v) => +v - 1);
}));
break;
case 'vt':
case 'vn':
rest.shift();
this[item].push(rest.map(Number));
break;
}
})
});
}
// Rename?
uv(nFace, nVert) {
const f = this.f[nFace];
const d = f[nVert][1];
return this.vt[d];
}
vNormal(nFace, nVert) {
if (!this.vn.length)
throw 'No vertex normal data';
const f = this.f[nFace];
const vI = f[nVert][0];
return this.vn[vI];
}
diffuse(uv, intensity = 1) {
if (!(this.textures.diffuse instanceof TGAImage)) {
throw 'No diffuse texture loaded';
}
const { diffuse } = this.textures;
const { width, height } = diffuse;
const [x, y] = uv;
return diffuse.get(x * width, y * height, intensity, 1.01);
}
}
window.Model = Model;
})();