-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTerrainPatchesInstancing.mts
111 lines (86 loc) · 4.16 KB
/
TerrainPatchesInstancing.mts
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
import { int } from "../Shared/Types.mjs";
import { BOTTOM, LEFT, RIGHT, TOP } from "../TerrainSystem/LodInfo.mjs";
import { PatchInstancing } from "../TerrainSystem/PatchInstancing.mjs";
export class TerrainPathcesInstancing extends PatchInstancing<pcx.MeshInstance> {
public enabled: boolean = false;
public get meshInstanceCount() { return this.data.length * LEFT * RIGHT * TOP * BOTTOM; }
public appendMeshInstances(arr: pcx.MeshInstance[], offset: int = 0) {
let i = 0;
for (let c = 0; c < this.data.length; c++) {
for (let l = 0; l < LEFT; l++) {
for (let r = 0; r < RIGHT; r++) {
for (let t = 0; t < TOP; t++) {
for (let b = 0; b < BOTTOM; b++) {
const chunk = this.data[c][l][r][t][b];
if (chunk.object) {
arr[i++ + offset] = chunk.object;
}
}
}
}
}
}
return i;
}
public begin(castShadow: boolean = false, receiveShadow: boolean = false) {
for (let c = 0; c < this.data.length; c++) {
for (let l = 0; l < LEFT; l++) {
for (let r = 0; r < RIGHT; r++) {
for (let t = 0; t < TOP; t++) {
for (let b = 0; b < BOTTOM; b++) {
const chunk = this.data[c][l][r][t][b];
const chunkObject = chunk.object;
chunk.count = 0;
chunk.hasChanges = false;
if (chunkObject) {
chunkObject.visible = false;
chunkObject.visibleThisFrame = false;
chunkObject.castShadow = castShadow;
chunkObject.receiveShadow = receiveShadow;
}
}
}
}
}
}
}
public end() {
for (let c = 0; c < this.data.length; c++) {
for (let l = 0; l < LEFT; l++) {
for (let r = 0; r < RIGHT; r++) {
for (let t = 0; t < TOP; t++) {
for (let b = 0; b < BOTTOM; b++) {
const chunk = this.data[c][l][r][t][b];
const chunkObject = chunk.object;
if (chunkObject && chunk.count > 0) {
chunkObject.instancingCount = chunk.count;
if (chunk.hasChanges && chunkObject.instancingData) {
// TODO: performance improvement
//chunkObject.instancingData.vertexBuffer?.unlock();
const length = chunk.count * 2;
const vertexBuffer = chunkObject.instancingData.vertexBuffer;
this._writeBuffer(vertexBuffer, chunk.data, length);
}
}
}
}
}
}
}
}
private _writeBuffer(vertexBuffer: pcx.VertexBuffer | null, data: Uint16Array, length: int) {
if (vertexBuffer) {
const device = vertexBuffer.device;
if (device.isWebGL2) {
const gl = (device as pcx.WebglGraphicsDevice).gl;
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer.impl.bufferId);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, data, 0, length);
}
else if (device.isWebGPU) {
const wgpu = (device as any).wgpu as GPUDevice;
const buffer = vertexBuffer.impl.buffer as GPUBuffer;
wgpu.queue.writeBuffer(buffer, 0, data, 0, length);
}
}
}
}