-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
Copy pathcreate-mesh.ts
92 lines (80 loc) · 2.35 KB
/
create-mesh.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
// deck.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import {lerp} from '@math.gl/core';
const DEFAULT_INDICES = new Uint32Array([0, 2, 1, 0, 3, 2]);
const DEFAULT_TEX_COORDS = new Float32Array([0, 1, 0, 0, 1, 0, 1, 1]);
/*
1 ---- 2
| |
| |
0 ---- 3
*/
/* eslint-disable max-statements */
export default function createMesh(bounds, resolution) {
if (!resolution) {
return createQuad(bounds);
}
const maxXSpan = Math.max(
Math.abs(bounds[0][0] - bounds[3][0]),
Math.abs(bounds[1][0] - bounds[2][0])
);
const maxYSpan = Math.max(
Math.abs(bounds[1][1] - bounds[0][1]),
Math.abs(bounds[2][1] - bounds[3][1])
);
const uCount = Math.ceil(maxXSpan / resolution) + 1;
const vCount = Math.ceil(maxYSpan / resolution) + 1;
const vertexCount = (uCount - 1) * (vCount - 1) * 6;
const indices = new Uint32Array(vertexCount);
const texCoords = new Float32Array(uCount * vCount * 2);
const positions = new Float64Array(uCount * vCount * 3);
// Tesselate
let vertex = 0;
let index = 0;
for (let u = 0; u < uCount; u++) {
const ut = u / (uCount - 1);
for (let v = 0; v < vCount; v++) {
const vt = v / (vCount - 1);
const p = interpolateQuad(bounds, ut, vt);
positions[vertex * 3 + 0] = p[0];
positions[vertex * 3 + 1] = p[1];
positions[vertex * 3 + 2] = p[2] || 0;
texCoords[vertex * 2 + 0] = ut;
texCoords[vertex * 2 + 1] = 1 - vt;
if (u > 0 && v > 0) {
indices[index++] = vertex - vCount;
indices[index++] = vertex - vCount - 1;
indices[index++] = vertex - 1;
indices[index++] = vertex - vCount;
indices[index++] = vertex - 1;
indices[index++] = vertex;
}
vertex++;
}
}
return {
vertexCount,
positions,
indices,
texCoords
};
}
function createQuad(bounds) {
const positions = new Float64Array(12);
// [[minX, minY], [minX, maxY], [maxX, maxY], [maxX, minY]]
for (let i = 0; i < bounds.length; i++) {
positions[i * 3 + 0] = bounds[i][0];
positions[i * 3 + 1] = bounds[i][1];
positions[i * 3 + 2] = bounds[i][2] || 0;
}
return {
vertexCount: 6,
positions,
indices: DEFAULT_INDICES,
texCoords: DEFAULT_TEX_COORDS
};
}
function interpolateQuad(quad, ut, vt) {
return lerp(lerp(quad[0], quad[1], vt), lerp(quad[3], quad[2], vt), ut);
}