-
Notifications
You must be signed in to change notification settings - Fork 317
Expand file tree
/
Copy pathTileGeometry.ts
More file actions
169 lines (151 loc) · 5.31 KB
/
Copy pathTileGeometry.ts
File metadata and controls
169 lines (151 loc) · 5.31 KB
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
import * as THREE from 'three';
import { computeBuffers, getBufferIndexSize }
from 'Core/Prefab/computeBufferTileGeometry';
import { GpuBufferAttributes, TileBuilder, TileBuilderParams }
from 'Core/Prefab/TileBuilder';
import { Coordinates, Extent } from '@itowns/geographic';
import { LRUCache } from 'lru-cache';
import OBB from 'Renderer/OBB';
type PartialTileBuilderParams =
Pick<TileBuilderParams, 'extent' | 'level'>
& Partial<TileBuilderParams>;
function defaultBuffers(
builder: TileBuilder<TileBuilderParams>,
params: PartialTileBuilderParams,
): GpuBufferAttributes {
const fullParams = {
disableSkirt: false,
hideSkirt: false,
buildIndexAndUv_0: true,
segments: 16,
coordinates: new Coordinates(builder.crs),
center: builder.center(params.extent!).clone(),
...params,
};
const buffers = computeBuffers(builder, fullParams);
const bufferAttributes = {
index: buffers.index
? new THREE.BufferAttribute(buffers.index, 1)
: null,
uvs: [
...(buffers.uvs[0]
? [new THREE.BufferAttribute(buffers.uvs[0], 2)]
: []
),
...(buffers.uvs[1]
? [new THREE.BufferAttribute(buffers.uvs[1], 1)]
: []),
],
position: new THREE.BufferAttribute(buffers.position, 3),
normal: new THREE.BufferAttribute(buffers.normal, 3),
};
return bufferAttributes;
}
export class TileGeometry extends THREE.BufferGeometry {
/** Oriented Bounding Box of the tile geometry. */
public OBB: OBB | null;
/** Ground area covered by this tile geometry. */
public extent: Extent;
/** Resolution of the tile geometry in segments per side. */
public segments: number;
/**
* [TileGeometry] instances are shared between tiles. Since a geometry
* handles its own GPU resource, it needs a reference counter to dispose of
* that resource only when it is discarded by every single owner of a
* reference to the geometry.
*/
// https://github.com/iTowns/itowns/pull/2440#discussion_r1860743294
// TODO: Remove nullability by reworking OBB:setFromExtent
private _refCount: {
count: number,
fn: () => void,
} | null;
public constructor(
builder: TileBuilder<TileBuilderParams>,
params: TileBuilderParams,
bufferAttributes: GpuBufferAttributes = defaultBuffers(builder, params),
) {
super();
this.extent = params.extent;
this.segments = params.segments;
this.setIndex(bufferAttributes.index);
this.setAttribute('position', bufferAttributes.position);
this.setAttribute('normal', bufferAttributes.normal);
this.setAttribute('uv', bufferAttributes.uvs[0]);
for (let i = 1; i < bufferAttributes.uvs.length; i++) {
this.setAttribute(`uv_${i}`, bufferAttributes.uvs[i]);
}
this.computeBoundingBox();
this.OBB = null;
if (params.hideSkirt) {
this.hideSkirt = params.hideSkirt;
}
this._refCount = null;
}
/**
* Enables or disables skirt rendering.
*
* @param toggle - Whether to hide the skirt; true hides, false shows.
*/
public set hideSkirt(toggle: boolean) {
this.setDrawRange(0, getBufferIndexSize(this.segments, toggle));
}
/**
* Initialize reference count for this geometry if it is currently null.
*
* @param cacheTile - The [Cache] used to store this geometry.
* @param keys - The [south, level, epsg] key of this geometry.
*/
public initRefCount(
cacheTile: LRUCache<string, TileGeometry>,
key: string,
): void {
if (this._refCount !== null) {
return;
}
this._refCount = {
count: 0,
fn: () => {
this._refCount!.count--;
if (this._refCount!.count <= 0) {
// To avoid remove index buffer and attribute buffer uv
// error un-bound buffer in webgl with VAO rendering.
// Could be removed if the attribute buffer deleting is
// taken into account in the buffer binding state
// (in THREE.WebGLBindingStates code).
this.index = null;
delete this.attributes.uv;
cacheTile.delete(key);
super.dispose();
// THREE.BufferGeometry.prototype.dispose.call(this);
}
},
};
}
/**
* Increase reference count.
*
* @throws If reference count has not been initialized.
*/
public increaseRefCount(): void {
if (this._refCount === null) {
throw new Error('[TileGeometry::increaseRefCount] '
+ 'Tried to increment an unitialized reference count.');
}
this._refCount.count++;
}
/**
* The current reference count of this [TileGeometry] if it has been
* initialized.
*/
public get refCount(): number | undefined {
return this._refCount?.count;
}
public override dispose(): void {
if (this._refCount == null) {
super.dispose();
} else {
this._refCount.fn();
}
}
}