@pirireis/webglobeplugins 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Math/tessellation/triangle-tessellation.js +6 -2
- package/package.json +1 -1
- package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.js +14 -2
- package/semiplugins/shape-on-terrain/terrain-polygon/data/worker.js +4 -1
- package/semiplugins/shape-on-terrain/terrain-polygon/terrain-polygon.js +62 -6
|
@@ -44,8 +44,12 @@ function radianCheck(point) {
|
|
|
44
44
|
}
|
|
45
45
|
const _3RealEdges = new Uint32Array([uint32Escape, 0, 1, 2, 0]);
|
|
46
46
|
const _2RealEdges_dismiss2 = new Uint32Array([uint32Escape, 0, 1, 2]);
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
// For 2-real-edge cases, the strip must traverse only the two real edges.
|
|
48
|
+
// Vertex indices are local: 0=p1, 1=p2, 2=p3.
|
|
49
|
+
// - dismiss1: real edges are (1-2) and (2-0) => strip 1->2->0
|
|
50
|
+
// - dismiss0: real edges are (2-0) and (0-1) => strip 2->0->1
|
|
51
|
+
const _2RealEdges_dismiss1 = new Uint32Array([uint32Escape, 1, 2, 0]);
|
|
52
|
+
const _2RealEdges_dismiss0 = new Uint32Array([uint32Escape, 2, 0, 1]);
|
|
49
53
|
const _1realEdge_0 = new Uint32Array([uint32Escape, 0, 1]);
|
|
50
54
|
const _1realEdge_1 = new Uint32Array([uint32Escape, 1, 2]);
|
|
51
55
|
const _1realEdge_2 = new Uint32Array([uint32Escape, 2, 0]);
|
package/package.json
CHANGED
|
@@ -125,6 +125,11 @@ function mergeAndSendResults() {
|
|
|
125
125
|
let vertexOffset = 3; // reserve 3 vertices
|
|
126
126
|
let arcCounter = BASE_REAL_EDGE_ARC_INDICES;
|
|
127
127
|
for (const out of validOutputs) {
|
|
128
|
+
const outPosVertexCount = Math.floor(out.vec3s.length / 3);
|
|
129
|
+
const outXYVertexCount = Math.floor(out.longLats.length / 2);
|
|
130
|
+
const outPickVertexCount = out.pickIndices ? out.pickIndices.length : Number.POSITIVE_INFINITY;
|
|
131
|
+
const outColorVertexCount = out.variativeColors ? Math.floor(out.variativeColors.length / 4) : Number.POSITIVE_INFINITY;
|
|
132
|
+
const outSafeVertexCount = Math.min(outPosVertexCount, outXYVertexCount, outPickVertexCount, outColorVertexCount);
|
|
128
133
|
merged.vec3s.set(out.vec3s, offsetVec3s);
|
|
129
134
|
offsetVec3s += out.vec3s.length;
|
|
130
135
|
for (let i = 0; i < out.indices.length; i++) {
|
|
@@ -133,8 +138,15 @@ function mergeAndSendResults() {
|
|
|
133
138
|
if (_arcState && merged.realEdgeArcIndices && out.realEdgeArcIndices) {
|
|
134
139
|
for (let i = 0; i < out.realEdgeArcIndices.length; i++) {
|
|
135
140
|
const realEdgeIndice = out.realEdgeArcIndices[i];
|
|
136
|
-
|
|
137
|
-
|
|
141
|
+
if (realEdgeIndice === uint32Escape) {
|
|
142
|
+
merged.realEdgeArcIndices[arcCounter++] = uint32Escape;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// Defensive: discard any out-of-range arc indices so we never
|
|
146
|
+
// generate a merged index that references missing attribute data.
|
|
147
|
+
merged.realEdgeArcIndices[arcCounter++] =
|
|
148
|
+
realEdgeIndice >= outSafeVertexCount ? uint32Escape : realEdgeIndice + vertexOffset;
|
|
149
|
+
}
|
|
138
150
|
}
|
|
139
151
|
}
|
|
140
152
|
offsetIndices += out.indices.length;
|
|
@@ -141,7 +141,10 @@ self.onmessage = (event) => {
|
|
|
141
141
|
output.realEdgeArcIndices[arcOffset + i] = uint32Escape;
|
|
142
142
|
}
|
|
143
143
|
else {
|
|
144
|
-
|
|
144
|
+
// Guard against occasional out-of-range arc indices.
|
|
145
|
+
// Invalid indices would crash ANGLE with "vertex buffer not big enough".
|
|
146
|
+
output.realEdgeArcIndices[arcOffset + i] =
|
|
147
|
+
value >= vertexCount ? uint32Escape : value + startVertex;
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
arcOffset += result.realEdgeArcIndices.length;
|
|
@@ -115,11 +115,18 @@ export class TerrainPolygonSemiPlugin {
|
|
|
115
115
|
this._drawPointsRangeIndexParams.elementBuffer = this._elementArrayBuffer;
|
|
116
116
|
}
|
|
117
117
|
insertBulk(polygons) {
|
|
118
|
-
// if (this._indexPolygonMap) {
|
|
119
118
|
let filteredPolygons = polygons.filter(inputCheck);
|
|
119
|
+
// Drop precision to 8 digits after dot before moving forward
|
|
120
|
+
filteredPolygons = filteredPolygons.map((p) => ({
|
|
121
|
+
...p,
|
|
122
|
+
geometry: p.geometry.map((g) => ({
|
|
123
|
+
...g,
|
|
124
|
+
vertices: g.vertices.map((v) => roundTo8(v)),
|
|
125
|
+
})),
|
|
126
|
+
}));
|
|
120
127
|
filteredPolygons = this._indexPolygonMap.insertBulk(filteredPolygons);
|
|
121
|
-
// }
|
|
122
128
|
this._workerContact.insertBulk(filteredPolygons);
|
|
129
|
+
this.globe.DrawRender(); // If the window is not focused, this may be needed to force processing.
|
|
123
130
|
}
|
|
124
131
|
deleteBulk(keys) {
|
|
125
132
|
this._workerContact.deleteBulk(keys);
|
|
@@ -149,6 +156,37 @@ export class TerrainPolygonSemiPlugin {
|
|
|
149
156
|
}
|
|
150
157
|
setBuffers(data) {
|
|
151
158
|
const gl = this.globe.gl;
|
|
159
|
+
const posVertexCount = Math.floor(data.vec3s.length / 3);
|
|
160
|
+
const xyVertexCount = Math.floor(data.longLats.length / 2);
|
|
161
|
+
let safeVertexCount = Math.min(posVertexCount, xyVertexCount);
|
|
162
|
+
if (this._options.pickable && data.pickIndices) {
|
|
163
|
+
safeVertexCount = Math.min(safeVertexCount, data.pickIndices.length);
|
|
164
|
+
}
|
|
165
|
+
if (this._options.variativeColorsOn && data.variativeColors) {
|
|
166
|
+
safeVertexCount = Math.min(safeVertexCount, Math.floor(data.variativeColors.length / 4));
|
|
167
|
+
}
|
|
168
|
+
// Guard against invalid indices referencing beyond uploaded attribute buffers.
|
|
169
|
+
// This prevents ANGLE "Vertex buffer is not big enough for the draw call" errors.
|
|
170
|
+
let maxTriangleIndex = -1;
|
|
171
|
+
for (let i = 0; i < data.indices.length; i++) {
|
|
172
|
+
const v = data.indices[i];
|
|
173
|
+
if (v > maxTriangleIndex)
|
|
174
|
+
maxTriangleIndex = v;
|
|
175
|
+
}
|
|
176
|
+
const trianglesInvalid = safeVertexCount === 0 || maxTriangleIndex >= safeVertexCount;
|
|
177
|
+
if (trianglesInvalid) {
|
|
178
|
+
console.warn("TerrainPolygonSemiPlugin: skipping draw due to invalid vertex/index sizing", {
|
|
179
|
+
posVertexCount,
|
|
180
|
+
xyVertexCount,
|
|
181
|
+
safeVertexCount,
|
|
182
|
+
indicesLength: data.indices.length,
|
|
183
|
+
maxTriangleIndex,
|
|
184
|
+
pickIndicesLength: data.pickIndices?.length ?? null,
|
|
185
|
+
variativeColorsLength: data.variativeColors?.length ?? null,
|
|
186
|
+
});
|
|
187
|
+
this._drawRangeIndexParams.drawRange.count = 0;
|
|
188
|
+
this._drawPointsRangeIndexParams.drawRange.count = 0;
|
|
189
|
+
}
|
|
152
190
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._elementArrayBuffer);
|
|
153
191
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data.indices, gl.STREAM_DRAW);
|
|
154
192
|
gl.bindBuffer(gl.ARRAY_BUFFER, this._vec3Buffer);
|
|
@@ -166,7 +204,25 @@ export class TerrainPolygonSemiPlugin {
|
|
|
166
204
|
if (this._options.drawEdges && data.realEdgeArcIndices) {
|
|
167
205
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._drawRealEdgeArcs.elementBuffer);
|
|
168
206
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data.realEdgeArcIndices, gl.STREAM_DRAW);
|
|
169
|
-
|
|
207
|
+
// If the edge index stream includes primitive-restart (0xFFFFFFFF) indices,
|
|
208
|
+
// the draw call requires PRIMITIVE_RESTART_FIXED_INDEX to be enabled.
|
|
209
|
+
// Also validate edge indices are within bounds.
|
|
210
|
+
let maxEdgeIndex = -1;
|
|
211
|
+
const PRIMITIVE_RESTART_INDEX = 0xFFFFFFFF;
|
|
212
|
+
for (let i = 0; i < data.realEdgeArcIndices.length; i++) {
|
|
213
|
+
const v = data.realEdgeArcIndices[i];
|
|
214
|
+
if (v === PRIMITIVE_RESTART_INDEX)
|
|
215
|
+
continue;
|
|
216
|
+
if (v > maxEdgeIndex)
|
|
217
|
+
maxEdgeIndex = v;
|
|
218
|
+
}
|
|
219
|
+
if (safeVertexCount === 0 || maxEdgeIndex >= safeVertexCount) {
|
|
220
|
+
console.warn("TerrainPolygonSemiPlugin: disabling edge draw due to invalid edge indices", { safeVertexCount, maxEdgeIndex, edgeIndexCount: data.realEdgeArcIndices.length });
|
|
221
|
+
this._drawRealEdgeArcs.drawRange.count = 0;
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
this._drawRealEdgeArcs.drawRange.count = data.realEdgeArcIndices.length;
|
|
225
|
+
}
|
|
170
226
|
}
|
|
171
227
|
else {
|
|
172
228
|
this._drawRealEdgeArcs.drawRange.count = 0;
|
|
@@ -230,9 +286,6 @@ export class TerrainPolygonSemiPlugin {
|
|
|
230
286
|
this._pickerDisplayer.clearTextures();
|
|
231
287
|
// gl.enable(gl.DEPTH_TEST);
|
|
232
288
|
}
|
|
233
|
-
else {
|
|
234
|
-
// gl.disable(gl.DEPTH_TEST);
|
|
235
|
-
}
|
|
236
289
|
gl.frontFace(gl.CW);
|
|
237
290
|
this._program.draw(this._vao, this._drawRangeIndexParams, this._uboHandler);
|
|
238
291
|
gl.frontFace(gl.CCW);
|
|
@@ -303,3 +356,6 @@ function getGlStates(gl) {
|
|
|
303
356
|
texture2DArray: gl.getParameter(gl.TEXTURE_BINDING_2D_ARRAY),
|
|
304
357
|
};
|
|
305
358
|
}
|
|
359
|
+
function roundTo8(n) {
|
|
360
|
+
return Math.round(n * 1e8) / 1e8;
|
|
361
|
+
}
|