@deck.gl/arcgis 9.4.0-beta.1 → 9.4.0-beta.4
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/dist/dist.dev.js +570 -523
- package/dist/index.cjs +2356 -9307
- package/dist/index.cjs.map +3 -3
- package/dist.min.js +4 -4
- package/package.json +6 -6
package/dist/dist.dev.js
CHANGED
|
@@ -3213,245 +3213,6 @@ Source: ${sourceLine}` : "";
|
|
|
3213
3213
|
}
|
|
3214
3214
|
});
|
|
3215
3215
|
|
|
3216
|
-
// ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-render-pipeline.js
|
|
3217
|
-
function mergeShaderLayout(baseLayout, overrideLayout) {
|
|
3218
|
-
const mergedLayout = {
|
|
3219
|
-
...baseLayout,
|
|
3220
|
-
attributes: baseLayout.attributes.map((attribute) => ({ ...attribute })),
|
|
3221
|
-
bindings: baseLayout.bindings.map((binding) => ({ ...binding }))
|
|
3222
|
-
};
|
|
3223
|
-
for (const attribute of overrideLayout?.attributes || []) {
|
|
3224
|
-
const baseAttribute = mergedLayout.attributes.find((attr) => attr.name === attribute.name);
|
|
3225
|
-
if (!baseAttribute) {
|
|
3226
|
-
import_core15.log.warn(`shader layout attribute ${attribute.name} not present in shader`);
|
|
3227
|
-
} else {
|
|
3228
|
-
baseAttribute.type = attribute.type || baseAttribute.type;
|
|
3229
|
-
baseAttribute.stepMode = attribute.stepMode || baseAttribute.stepMode;
|
|
3230
|
-
}
|
|
3231
|
-
}
|
|
3232
|
-
for (const binding of overrideLayout?.bindings || []) {
|
|
3233
|
-
const baseBinding = getShaderLayoutBindingByName(mergedLayout, binding.name);
|
|
3234
|
-
if (!baseBinding) {
|
|
3235
|
-
import_core15.log.warn(`shader layout binding ${binding.name} not present in shader`);
|
|
3236
|
-
continue;
|
|
3237
|
-
}
|
|
3238
|
-
Object.assign(baseBinding, binding);
|
|
3239
|
-
}
|
|
3240
|
-
return mergedLayout;
|
|
3241
|
-
}
|
|
3242
|
-
function getShaderLayoutBindingByName(shaderLayout, bindingName) {
|
|
3243
|
-
return shaderLayout.bindings.find((binding) => binding.name === bindingName || binding.name === `${bindingName}Uniforms` || `${binding.name}Uniforms` === bindingName);
|
|
3244
|
-
}
|
|
3245
|
-
function getBindingValueForLayoutBinding(bindings, bindingName) {
|
|
3246
|
-
return bindings[bindingName] || bindings[`${bindingName}Uniforms`] || bindings[bindingName.replace(/Uniforms$/, "")];
|
|
3247
|
-
}
|
|
3248
|
-
var import_core15, WEBGLRenderPipeline;
|
|
3249
|
-
var init_webgl_render_pipeline = __esm({
|
|
3250
|
-
"../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-render-pipeline.js"() {
|
|
3251
|
-
import_core15 = __toESM(require_core2(), 1);
|
|
3252
|
-
init_set_uniform();
|
|
3253
|
-
init_webgl_buffer();
|
|
3254
|
-
init_webgl_framebuffer();
|
|
3255
|
-
init_webgl_texture();
|
|
3256
|
-
init_webgl_texture_view();
|
|
3257
|
-
WEBGLRenderPipeline = class extends import_core15.RenderPipeline {
|
|
3258
|
-
/** The WebGL device that created this render pipeline */
|
|
3259
|
-
device;
|
|
3260
|
-
/** Handle to underlying WebGL program */
|
|
3261
|
-
handle;
|
|
3262
|
-
/** vertex shader */
|
|
3263
|
-
vs;
|
|
3264
|
-
/** fragment shader */
|
|
3265
|
-
fs;
|
|
3266
|
-
/** The layout extracted from shader by WebGL introspection APIs */
|
|
3267
|
-
introspectedLayout;
|
|
3268
|
-
/** Compatibility path for direct pipeline.setBindings() usage */
|
|
3269
|
-
bindings = {};
|
|
3270
|
-
/** Compatibility path for direct pipeline.uniforms usage */
|
|
3271
|
-
uniforms = {};
|
|
3272
|
-
/** WebGL varyings */
|
|
3273
|
-
varyings = null;
|
|
3274
|
-
_uniformCount = 0;
|
|
3275
|
-
_uniformSetters = {};
|
|
3276
|
-
// TODO are these used?
|
|
3277
|
-
get [Symbol.toStringTag]() {
|
|
3278
|
-
return "WEBGLRenderPipeline";
|
|
3279
|
-
}
|
|
3280
|
-
constructor(device, props) {
|
|
3281
|
-
super(device, props);
|
|
3282
|
-
this.device = device;
|
|
3283
|
-
const webglSharedRenderPipeline = this.sharedRenderPipeline || this.device._createSharedRenderPipelineWebGL(props);
|
|
3284
|
-
this.sharedRenderPipeline = webglSharedRenderPipeline;
|
|
3285
|
-
this.handle = webglSharedRenderPipeline.handle;
|
|
3286
|
-
this.vs = webglSharedRenderPipeline.vs;
|
|
3287
|
-
this.fs = webglSharedRenderPipeline.fs;
|
|
3288
|
-
this.linkStatus = webglSharedRenderPipeline.linkStatus;
|
|
3289
|
-
this.introspectedLayout = webglSharedRenderPipeline.introspectedLayout;
|
|
3290
|
-
this.device._setWebGLDebugMetadata(this.handle, this, { spector: { id: this.props.id } });
|
|
3291
|
-
this.shaderLayout = props.shaderLayout ? mergeShaderLayout(this.introspectedLayout, props.shaderLayout) : this.introspectedLayout;
|
|
3292
|
-
}
|
|
3293
|
-
destroy() {
|
|
3294
|
-
if (this.destroyed) {
|
|
3295
|
-
return;
|
|
3296
|
-
}
|
|
3297
|
-
if (this.sharedRenderPipeline && !this.props._sharedRenderPipeline) {
|
|
3298
|
-
this.sharedRenderPipeline.destroy();
|
|
3299
|
-
}
|
|
3300
|
-
this.destroyResource();
|
|
3301
|
-
}
|
|
3302
|
-
/** @deprecated Set bindings on RenderPass instead. Will be removed in the next major release. */
|
|
3303
|
-
setBindings(bindings, options) {
|
|
3304
|
-
const flatBindings = (0, import_core15.flattenBindingsByGroup)((0, import_core15.normalizeBindingsByGroup)(this.shaderLayout, bindings));
|
|
3305
|
-
for (const [name, value] of Object.entries(flatBindings)) {
|
|
3306
|
-
const binding = getShaderLayoutBindingByName(this.shaderLayout, name);
|
|
3307
|
-
if (!binding) {
|
|
3308
|
-
const validBindings = this.shaderLayout.bindings.map((binding_) => `"${binding_.name}"`).join(", ");
|
|
3309
|
-
if (!options?.disableWarnings) {
|
|
3310
|
-
import_core15.log.warn(`No binding "${name}" in render pipeline "${this.id}", expected one of ${validBindings}`, value)();
|
|
3311
|
-
}
|
|
3312
|
-
} else {
|
|
3313
|
-
if (!value) {
|
|
3314
|
-
import_core15.log.warn(`Unsetting binding "${name}" in render pipeline "${this.id}"`)();
|
|
3315
|
-
}
|
|
3316
|
-
switch (binding.type) {
|
|
3317
|
-
case "uniform":
|
|
3318
|
-
if (!(value instanceof WEBGLBuffer) && !(value.buffer instanceof WEBGLBuffer)) {
|
|
3319
|
-
throw new Error("buffer value");
|
|
3320
|
-
}
|
|
3321
|
-
break;
|
|
3322
|
-
case "texture":
|
|
3323
|
-
if (!(value instanceof WEBGLTextureView || value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
|
|
3324
|
-
throw new Error(`${this} Bad texture binding for ${name}`);
|
|
3325
|
-
}
|
|
3326
|
-
break;
|
|
3327
|
-
case "sampler":
|
|
3328
|
-
import_core15.log.warn(`Ignoring sampler ${name}`)();
|
|
3329
|
-
break;
|
|
3330
|
-
default:
|
|
3331
|
-
throw new Error(binding.type);
|
|
3332
|
-
}
|
|
3333
|
-
this.bindings[name] = value;
|
|
3334
|
-
}
|
|
3335
|
-
}
|
|
3336
|
-
}
|
|
3337
|
-
/** @todo needed for portable model
|
|
3338
|
-
* @note The WebGL API is offers many ways to draw things
|
|
3339
|
-
* This function unifies those ways into a single call using common parameters with sane defaults
|
|
3340
|
-
*/
|
|
3341
|
-
draw(options) {
|
|
3342
|
-
const webglRenderPass = options.renderPass;
|
|
3343
|
-
const drawBindings = options.bindGroups ? (0, import_core15.flattenBindingsByGroup)(options.bindGroups) : options.bindings || this.bindings;
|
|
3344
|
-
webglRenderPass.setPipeline(this);
|
|
3345
|
-
webglRenderPass.setBindings(drawBindings);
|
|
3346
|
-
webglRenderPass.setVertexArray(options.vertexArray);
|
|
3347
|
-
return webglRenderPass.draw({
|
|
3348
|
-
parameters: options.parameters,
|
|
3349
|
-
topology: options.topology,
|
|
3350
|
-
isInstanced: options.isInstanced,
|
|
3351
|
-
vertexCount: options.vertexCount,
|
|
3352
|
-
indexCount: options.indexCount,
|
|
3353
|
-
instanceCount: options.instanceCount,
|
|
3354
|
-
firstVertex: options.firstVertex,
|
|
3355
|
-
firstIndex: options.firstIndex,
|
|
3356
|
-
firstInstance: options.firstInstance,
|
|
3357
|
-
baseVertex: options.baseVertex,
|
|
3358
|
-
transformFeedback: options.transformFeedback,
|
|
3359
|
-
uniforms: options.uniforms
|
|
3360
|
-
});
|
|
3361
|
-
}
|
|
3362
|
-
/**
|
|
3363
|
-
* Checks if all texture-values uniforms are renderable (i.e. loaded)
|
|
3364
|
-
* Update a texture if needed (e.g. from video)
|
|
3365
|
-
* Note: This is currently done before every draw call
|
|
3366
|
-
*/
|
|
3367
|
-
_areTexturesRenderable(bindings) {
|
|
3368
|
-
let texturesRenderable = true;
|
|
3369
|
-
for (const bindingInfo of this.shaderLayout.bindings) {
|
|
3370
|
-
if (!getBindingValueForLayoutBinding(bindings, bindingInfo.name)) {
|
|
3371
|
-
import_core15.log.warn(`Binding ${bindingInfo.name} not found in ${this.id}`)();
|
|
3372
|
-
texturesRenderable = false;
|
|
3373
|
-
}
|
|
3374
|
-
}
|
|
3375
|
-
return texturesRenderable;
|
|
3376
|
-
}
|
|
3377
|
-
/** Apply any bindings (before each draw call) */
|
|
3378
|
-
_applyBindings(bindings, _options) {
|
|
3379
|
-
this._syncLinkStatus();
|
|
3380
|
-
if (this.linkStatus !== "success") {
|
|
3381
|
-
return;
|
|
3382
|
-
}
|
|
3383
|
-
const { gl } = this.device;
|
|
3384
|
-
gl.useProgram(this.handle);
|
|
3385
|
-
let textureUnit = 0;
|
|
3386
|
-
let uniformBufferIndex = 0;
|
|
3387
|
-
for (const binding of this.shaderLayout.bindings) {
|
|
3388
|
-
const value = getBindingValueForLayoutBinding(bindings, binding.name);
|
|
3389
|
-
if (!value) {
|
|
3390
|
-
throw new Error(`No value for binding ${binding.name} in ${this.id}`);
|
|
3391
|
-
}
|
|
3392
|
-
switch (binding.type) {
|
|
3393
|
-
case "uniform":
|
|
3394
|
-
const { name } = binding;
|
|
3395
|
-
const location = gl.getUniformBlockIndex(this.handle, name);
|
|
3396
|
-
if (location === 4294967295) {
|
|
3397
|
-
throw new Error(`Invalid uniform block name ${name}`);
|
|
3398
|
-
}
|
|
3399
|
-
gl.uniformBlockBinding(this.handle, location, uniformBufferIndex);
|
|
3400
|
-
if (value instanceof WEBGLBuffer) {
|
|
3401
|
-
gl.bindBufferBase(35345, uniformBufferIndex, value.handle);
|
|
3402
|
-
} else {
|
|
3403
|
-
const bufferBinding = value;
|
|
3404
|
-
gl.bindBufferRange(35345, uniformBufferIndex, bufferBinding.buffer.handle, bufferBinding.offset || 0, bufferBinding.size || bufferBinding.buffer.byteLength - (bufferBinding.offset || 0));
|
|
3405
|
-
}
|
|
3406
|
-
uniformBufferIndex += 1;
|
|
3407
|
-
break;
|
|
3408
|
-
case "texture":
|
|
3409
|
-
if (!(value instanceof WEBGLTextureView || value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
|
|
3410
|
-
throw new Error("texture");
|
|
3411
|
-
}
|
|
3412
|
-
let texture;
|
|
3413
|
-
if (value instanceof WEBGLTextureView) {
|
|
3414
|
-
texture = value.texture;
|
|
3415
|
-
} else if (value instanceof WEBGLTexture) {
|
|
3416
|
-
texture = value;
|
|
3417
|
-
} else if (value instanceof WEBGLFramebuffer && value.colorAttachments[0] instanceof WEBGLTextureView) {
|
|
3418
|
-
import_core15.log.warn("Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead")();
|
|
3419
|
-
texture = value.colorAttachments[0].texture;
|
|
3420
|
-
} else {
|
|
3421
|
-
throw new Error("No texture");
|
|
3422
|
-
}
|
|
3423
|
-
gl.activeTexture(33984 + textureUnit);
|
|
3424
|
-
gl.bindTexture(texture.glTarget, texture.handle);
|
|
3425
|
-
textureUnit += 1;
|
|
3426
|
-
break;
|
|
3427
|
-
case "sampler":
|
|
3428
|
-
break;
|
|
3429
|
-
case "storage":
|
|
3430
|
-
case "read-only-storage":
|
|
3431
|
-
throw new Error(`binding type '${binding.type}' not supported in WebGL`);
|
|
3432
|
-
}
|
|
3433
|
-
}
|
|
3434
|
-
}
|
|
3435
|
-
/**
|
|
3436
|
-
* Due to program sharing, uniforms need to be reset before every draw call
|
|
3437
|
-
* (though caching will avoid redundant WebGL calls)
|
|
3438
|
-
*/
|
|
3439
|
-
_applyUniforms(uniforms) {
|
|
3440
|
-
for (const uniformLayout of this.shaderLayout.uniforms || []) {
|
|
3441
|
-
const { name, location, type, textureUnit } = uniformLayout;
|
|
3442
|
-
const value = uniforms[name] ?? textureUnit;
|
|
3443
|
-
if (value !== void 0) {
|
|
3444
|
-
setUniform(this.device.gl, location, type, value);
|
|
3445
|
-
}
|
|
3446
|
-
}
|
|
3447
|
-
}
|
|
3448
|
-
_syncLinkStatus() {
|
|
3449
|
-
this.linkStatus = this.sharedRenderPipeline.linkStatus;
|
|
3450
|
-
}
|
|
3451
|
-
};
|
|
3452
|
-
}
|
|
3453
|
-
});
|
|
3454
|
-
|
|
3455
3216
|
// ../../node_modules/@luma.gl/webgl/dist/adapter/converters/webgl-shadertypes.js
|
|
3456
3217
|
function convertDataTypeToGLDataType(normalizedType) {
|
|
3457
3218
|
return NORMALIZED_SHADER_TYPE_TO_WEBGL[normalizedType];
|
|
@@ -3534,13 +3295,13 @@ Source: ${sourceLine}` : "";
|
|
|
3534
3295
|
});
|
|
3535
3296
|
|
|
3536
3297
|
// ../../node_modules/@luma.gl/webgl/dist/adapter/helpers/get-shader-layout-from-glsl.js
|
|
3537
|
-
function getShaderLayoutFromGLSL(gl, program) {
|
|
3298
|
+
function getShaderLayoutFromGLSL(gl, program, options = {}) {
|
|
3538
3299
|
const shaderLayout = {
|
|
3539
3300
|
attributes: [],
|
|
3540
3301
|
bindings: []
|
|
3541
3302
|
};
|
|
3542
3303
|
shaderLayout.attributes = readAttributeDeclarations(gl, program);
|
|
3543
|
-
const uniformBlocks = readUniformBlocks(gl, program);
|
|
3304
|
+
const uniformBlocks = readUniformBlocks(gl, program, options);
|
|
3544
3305
|
for (const uniformBlock of uniformBlocks) {
|
|
3545
3306
|
const uniforms2 = uniformBlock.uniforms.map((uniform) => ({
|
|
3546
3307
|
name: uniform.name,
|
|
@@ -3554,7 +3315,7 @@ Source: ${sourceLine}` : "";
|
|
|
3554
3315
|
name: uniformBlock.name,
|
|
3555
3316
|
group: 0,
|
|
3556
3317
|
location: uniformBlock.location,
|
|
3557
|
-
visibility: (uniformBlock.vertex ? 1 : 0)
|
|
3318
|
+
visibility: (uniformBlock.vertex ? 1 : 0) | (uniformBlock.fragment ? 2 : 0),
|
|
3558
3319
|
minBindingSize: uniformBlock.byteLength,
|
|
3559
3320
|
uniforms: uniforms2
|
|
3560
3321
|
});
|
|
@@ -3624,7 +3385,7 @@ Source: ${sourceLine}` : "";
|
|
|
3624
3385
|
}
|
|
3625
3386
|
const { name, type: glUniformType, size } = activeInfo;
|
|
3626
3387
|
const uniformType = convertGLUniformTypeToShaderVariableType(glUniformType);
|
|
3627
|
-
const { type, components } = (0,
|
|
3388
|
+
const { type, components } = (0, import_core15.getVariableShaderTypeInfo)(uniformType);
|
|
3628
3389
|
varyings.push({ location, name, type, size: size * components });
|
|
3629
3390
|
}
|
|
3630
3391
|
varyings.sort((a, b) => a.location - b.location);
|
|
@@ -3661,84 +3422,530 @@ Source: ${sourceLine}` : "";
|
|
|
3661
3422
|
};
|
|
3662
3423
|
uniforms.push(arrayElementUniformInfo);
|
|
3663
3424
|
}
|
|
3664
|
-
}
|
|
3665
|
-
}
|
|
3666
|
-
return uniforms;
|
|
3667
|
-
}
|
|
3668
|
-
function readUniformBlocks(gl, program) {
|
|
3669
|
-
const
|
|
3670
|
-
const
|
|
3671
|
-
const
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
return uniforms;
|
|
3428
|
+
}
|
|
3429
|
+
function readUniformBlocks(gl, program, options) {
|
|
3430
|
+
const uniformBlocks = [];
|
|
3431
|
+
const knownBlocksByIndex = getKnownUniformBlocksByIndex(gl, program, options);
|
|
3432
|
+
for (const [blockIndex, uniformBlock] of knownBlocksByIndex) {
|
|
3433
|
+
uniformBlocks.push(uniformBlock);
|
|
3434
|
+
try {
|
|
3435
|
+
const reflectedUniformBlock = readReflectedUniformBlock(gl, program, blockIndex, uniformBlock.name);
|
|
3436
|
+
validateReflectedUniformBlock(reflectedUniformBlock, uniformBlock);
|
|
3437
|
+
} catch (error) {
|
|
3438
|
+
const message2 = error instanceof Error ? error.message : String(error);
|
|
3439
|
+
import_core15.log.once(0, `WebGL uniform block reflection failed for "${uniformBlock.name}"; using supplied std140 metadata. ${message2}`)();
|
|
3440
|
+
}
|
|
3441
|
+
}
|
|
3442
|
+
const blockCount = gl.getProgramParameter(program, 35382);
|
|
3443
|
+
if (!Number.isInteger(blockCount) || blockCount < 0) {
|
|
3444
|
+
throw new Error(`Failed to reflect WebGL uniform blocks: ACTIVE_UNIFORM_BLOCKS returned ${String(blockCount)}`);
|
|
3445
|
+
}
|
|
3446
|
+
for (let blockIndex = 0; blockIndex < blockCount; blockIndex++) {
|
|
3447
|
+
if (!knownBlocksByIndex.has(blockIndex)) {
|
|
3448
|
+
uniformBlocks.push(readReflectedUniformBlock(gl, program, blockIndex));
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
uniformBlocks.sort((a, b) => a.location - b.location);
|
|
3452
|
+
return uniformBlocks;
|
|
3453
|
+
}
|
|
3454
|
+
function validateReflectedUniformBlock(reflectedUniformBlock, knownUniformBlock) {
|
|
3455
|
+
for (const reflectedUniform of reflectedUniformBlock.uniforms) {
|
|
3456
|
+
const knownUniform = knownUniformBlock.uniforms.find((uniform) => reflectedUniform.name === uniform.name || reflectedUniform.name.endsWith(`.${uniform.name}`));
|
|
3457
|
+
if (!knownUniform) {
|
|
3458
|
+
throw new Error(`Failed to validate WebGL uniform block "${knownUniformBlock.name}": reflected unexpected member "${reflectedUniform.name}"`);
|
|
3459
|
+
}
|
|
3460
|
+
if (reflectedUniform.format !== knownUniform.format || reflectedUniform.arrayLength !== knownUniform.arrayLength || reflectedUniform.byteOffset !== knownUniform.byteOffset || reflectedUniform.byteStride !== knownUniform.byteStride) {
|
|
3461
|
+
throw new Error(`Failed to validate WebGL uniform block "${knownUniformBlock.name}": reflected layout for "${reflectedUniform.name}" does not match supplied std140 metadata`);
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
function getKnownUniformBlocksByIndex(gl, program, options) {
|
|
3466
|
+
const knownUniformBlocks = /* @__PURE__ */ new Map();
|
|
3467
|
+
for (const uniformBlockLayout of options.uniformBlockLayouts || []) {
|
|
3468
|
+
knownUniformBlocks.set(uniformBlockLayout.name, makeUniformBlockBindingFromTypes(uniformBlockLayout));
|
|
3469
|
+
}
|
|
3470
|
+
for (const binding of options.shaderLayout?.bindings || []) {
|
|
3471
|
+
if (isUsableUniformBlockBinding(binding)) {
|
|
3472
|
+
knownUniformBlocks.set(binding.name, binding);
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
const knownBlocksByIndex = /* @__PURE__ */ new Map();
|
|
3476
|
+
for (const binding of knownUniformBlocks.values()) {
|
|
3477
|
+
const resolvedBlock = getActiveUniformBlockIndex(gl, program, binding.name);
|
|
3478
|
+
if (!resolvedBlock) {
|
|
3479
|
+
continue;
|
|
3480
|
+
}
|
|
3481
|
+
const { blockIndex, blockName } = resolvedBlock;
|
|
3482
|
+
if (knownBlocksByIndex.has(blockIndex)) {
|
|
3483
|
+
throw new Error(`Multiple supplied uniform block layouts resolve to active WebGL block "${blockName}"`);
|
|
3484
|
+
}
|
|
3485
|
+
knownBlocksByIndex.set(blockIndex, {
|
|
3486
|
+
name: blockName,
|
|
3487
|
+
location: blockIndex,
|
|
3488
|
+
byteLength: binding.minBindingSize,
|
|
3489
|
+
vertex: Boolean(binding.visibility && binding.visibility & 1),
|
|
3490
|
+
fragment: Boolean(binding.visibility && binding.visibility & 2),
|
|
3491
|
+
uniformCount: binding.uniforms.length,
|
|
3492
|
+
uniforms: binding.uniforms.map((uniform) => ({ ...uniform }))
|
|
3493
|
+
});
|
|
3494
|
+
}
|
|
3495
|
+
return knownBlocksByIndex;
|
|
3496
|
+
}
|
|
3497
|
+
function getActiveUniformBlockIndex(gl, program, blockName) {
|
|
3498
|
+
const blockNames = blockName.endsWith("Uniforms") ? [blockName, blockName.slice(0, -"Uniforms".length)] : [blockName, `${blockName}Uniforms`];
|
|
3499
|
+
for (const candidateBlockName of blockNames) {
|
|
3500
|
+
const blockIndex = gl.getUniformBlockIndex(program, candidateBlockName);
|
|
3501
|
+
if (blockIndex !== 4294967295) {
|
|
3502
|
+
if (!Number.isInteger(blockIndex) || blockIndex < 0) {
|
|
3503
|
+
throw new Error(`Failed to resolve WebGL uniform block "${candidateBlockName}": getUniformBlockIndex returned ${String(blockIndex)}`);
|
|
3504
|
+
}
|
|
3505
|
+
return { blockIndex, blockName: candidateBlockName };
|
|
3506
|
+
}
|
|
3507
|
+
}
|
|
3508
|
+
return null;
|
|
3509
|
+
}
|
|
3510
|
+
function readReflectedUniformBlock(gl, program, blockIndex, knownBlockName) {
|
|
3511
|
+
const blockName = knownBlockName || gl.getActiveUniformBlockName(program, blockIndex);
|
|
3512
|
+
if (!blockName) {
|
|
3513
|
+
throw new Error(`Failed to reflect WebGL uniform block at index ${blockIndex}: missing block name`);
|
|
3514
|
+
}
|
|
3515
|
+
const getBlockParameter = (pname, label) => {
|
|
3516
|
+
const value = gl.getActiveUniformBlockParameter(program, blockIndex, pname);
|
|
3517
|
+
if (value === null || value === void 0) {
|
|
3518
|
+
throw new Error(`Failed to reflect WebGL uniform block "${blockName}": ${label} returned null`);
|
|
3519
|
+
}
|
|
3520
|
+
return value;
|
|
3521
|
+
};
|
|
3522
|
+
const location = getFiniteInteger(getBlockParameter(35391, "UNIFORM_BLOCK_BINDING"), blockName, "UNIFORM_BLOCK_BINDING", 0);
|
|
3523
|
+
const byteLength = getFiniteInteger(getBlockParameter(35392, "UNIFORM_BLOCK_DATA_SIZE"), blockName, "UNIFORM_BLOCK_DATA_SIZE", 0);
|
|
3524
|
+
const uniformCount = getFiniteInteger(getBlockParameter(35394, "UNIFORM_BLOCK_ACTIVE_UNIFORMS"), blockName, "UNIFORM_BLOCK_ACTIVE_UNIFORMS", 0);
|
|
3525
|
+
const uniformIndices = getNumericArray(getBlockParameter(35395, "UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES"), blockName, "UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES", uniformCount);
|
|
3526
|
+
const uniformTypes = getActiveUniformValues(gl, program, uniformIndices, 35383, "UNIFORM_TYPE", blockName, uniformCount);
|
|
3527
|
+
const uniformArrayLengths = getActiveUniformValues(gl, program, uniformIndices, 35384, "UNIFORM_SIZE", blockName, uniformCount);
|
|
3528
|
+
const uniformBlockIndices = getActiveUniformValues(gl, program, uniformIndices, 35386, "UNIFORM_BLOCK_INDEX", blockName, uniformCount);
|
|
3529
|
+
const uniformOffsets = getActiveUniformValues(gl, program, uniformIndices, 35387, "UNIFORM_OFFSET", blockName, uniformCount);
|
|
3530
|
+
const uniformStrides = getActiveUniformValues(gl, program, uniformIndices, 35388, "UNIFORM_ARRAY_STRIDE", blockName, uniformCount);
|
|
3531
|
+
const uniforms = [];
|
|
3532
|
+
for (let uniformPosition = 0; uniformPosition < uniformCount; uniformPosition++) {
|
|
3533
|
+
if (uniformBlockIndices[uniformPosition] !== blockIndex) {
|
|
3534
|
+
throw new Error(`Failed to reflect WebGL uniform block "${blockName}": active uniform index ${uniformIndices[uniformPosition]} belongs to block ${uniformBlockIndices[uniformPosition]}, expected ${blockIndex}`);
|
|
3535
|
+
}
|
|
3536
|
+
const uniformIndex = uniformIndices[uniformPosition];
|
|
3537
|
+
const activeInfo = gl.getActiveUniform(program, uniformIndex);
|
|
3538
|
+
if (!activeInfo) {
|
|
3539
|
+
throw new Error(`Failed to reflect WebGL uniform block "${blockName}": getActiveUniform(${uniformIndex}) returned null`);
|
|
3540
|
+
}
|
|
3541
|
+
const uniformType = getFiniteInteger(uniformTypes[uniformPosition], blockName, `UNIFORM_TYPE[${uniformPosition}]`, 1);
|
|
3542
|
+
const arrayLength = getFiniteInteger(uniformArrayLengths[uniformPosition], blockName, `UNIFORM_SIZE[${uniformPosition}]`, 1);
|
|
3543
|
+
const byteOffset = getFiniteInteger(uniformOffsets[uniformPosition], blockName, `UNIFORM_OFFSET[${uniformPosition}]`, 0);
|
|
3544
|
+
const byteStride = getFiniteInteger(uniformStrides[uniformPosition], blockName, `UNIFORM_ARRAY_STRIDE[${uniformPosition}]`, 0);
|
|
3545
|
+
if (activeInfo.type !== uniformType || activeInfo.size !== arrayLength) {
|
|
3546
|
+
throw new Error(`Failed to reflect WebGL uniform block "${blockName}": getActiveUniform(${uniformIndex}) disagrees with getActiveUniforms`);
|
|
3547
|
+
}
|
|
3548
|
+
uniforms.push({
|
|
3549
|
+
name: activeInfo.name,
|
|
3550
|
+
format: convertGLUniformTypeToShaderVariableType(uniformType),
|
|
3551
|
+
arrayLength,
|
|
3552
|
+
byteOffset,
|
|
3553
|
+
byteStride
|
|
3554
|
+
});
|
|
3555
|
+
}
|
|
3556
|
+
const blockInfo = {
|
|
3557
|
+
name: blockName,
|
|
3558
|
+
location,
|
|
3559
|
+
byteLength,
|
|
3560
|
+
vertex: Boolean(getBlockParameter(35396, "UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER")),
|
|
3561
|
+
fragment: Boolean(getBlockParameter(35398, "UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER")),
|
|
3562
|
+
uniformCount,
|
|
3563
|
+
uniforms
|
|
3564
|
+
};
|
|
3565
|
+
const uniformInstancePrefixes = new Set(blockInfo.uniforms.map((uniform) => uniform.name.split(".")[0]).filter((instanceName) => Boolean(instanceName)));
|
|
3566
|
+
const blockAlias = blockInfo.name.replace(/Uniforms$/, "");
|
|
3567
|
+
if (uniformInstancePrefixes.size === 1 && !uniformInstancePrefixes.has(blockInfo.name) && !uniformInstancePrefixes.has(blockAlias)) {
|
|
3568
|
+
const [instanceName] = uniformInstancePrefixes;
|
|
3569
|
+
import_core15.log.warn(`Uniform block "${blockInfo.name}" uses GLSL instance "${instanceName}". luma.gl binds uniform buffers by block name ("${blockInfo.name}") and alias ("${blockAlias}"). Prefer matching the instance name to one of those to avoid confusing silent mismatches.`)();
|
|
3570
|
+
}
|
|
3571
|
+
return blockInfo;
|
|
3572
|
+
}
|
|
3573
|
+
function getActiveUniformValues(gl, program, uniformIndices, pname, label, blockName, expectedLength) {
|
|
3574
|
+
const values = gl.getActiveUniforms(program, uniformIndices, pname);
|
|
3575
|
+
if (values === null) {
|
|
3576
|
+
throw new Error(`Failed to reflect WebGL uniform block "${blockName}": ${label} returned null`);
|
|
3577
|
+
}
|
|
3578
|
+
return getNumericArray(values, blockName, label, expectedLength);
|
|
3579
|
+
}
|
|
3580
|
+
function getNumericArray(value, blockName, label, expectedLength) {
|
|
3581
|
+
if (!Array.isArray(value) && !ArrayBuffer.isView(value)) {
|
|
3582
|
+
throw new Error(`Failed to reflect WebGL uniform block "${blockName}": ${label} returned a non-array value`);
|
|
3583
|
+
}
|
|
3584
|
+
const values = Array.from(value);
|
|
3585
|
+
if (values.length !== expectedLength || values.some((item) => !Number.isInteger(item))) {
|
|
3586
|
+
throw new Error(`Failed to reflect WebGL uniform block "${blockName}": ${label} returned ${values.length} invalid values, expected ${expectedLength}`);
|
|
3587
|
+
}
|
|
3588
|
+
return values;
|
|
3589
|
+
}
|
|
3590
|
+
function getFiniteInteger(value, blockName, label, minimum) {
|
|
3591
|
+
if (!Number.isInteger(value) || value < minimum) {
|
|
3592
|
+
throw new Error(`Failed to reflect WebGL uniform block "${blockName}": ${label} returned ${String(value)}`);
|
|
3593
|
+
}
|
|
3594
|
+
return value;
|
|
3595
|
+
}
|
|
3596
|
+
function makeUniformBlockBindingFromTypes(uniformBlockLayout) {
|
|
3597
|
+
const shaderBlockLayout = (0, import_core15.makeShaderBlockLayout)(uniformBlockLayout.uniformTypes, {
|
|
3598
|
+
layout: "std140"
|
|
3599
|
+
});
|
|
3600
|
+
const uniforms = getUniformInfosFromTypes(uniformBlockLayout.uniformTypes, shaderBlockLayout.fields);
|
|
3601
|
+
return {
|
|
3602
|
+
type: "uniform",
|
|
3603
|
+
name: uniformBlockLayout.name,
|
|
3604
|
+
group: 0,
|
|
3605
|
+
location: 0,
|
|
3606
|
+
minBindingSize: shaderBlockLayout.byteLength,
|
|
3607
|
+
uniforms
|
|
3608
|
+
};
|
|
3609
|
+
}
|
|
3610
|
+
function getUniformInfosFromTypes(uniformTypes, fields) {
|
|
3611
|
+
const uniforms = [];
|
|
3612
|
+
const addType = (name, type) => {
|
|
3613
|
+
if (typeof type === "string") {
|
|
3614
|
+
const field = fields[name];
|
|
3615
|
+
if (!field) {
|
|
3616
|
+
throw new Error(`Missing std140 layout field ${name}`);
|
|
3617
|
+
}
|
|
3618
|
+
uniforms.push({
|
|
3619
|
+
name,
|
|
3620
|
+
format: field.shaderType,
|
|
3621
|
+
arrayLength: 1,
|
|
3622
|
+
byteOffset: field.offset * 4,
|
|
3623
|
+
byteStride: 0
|
|
3624
|
+
});
|
|
3625
|
+
return;
|
|
3626
|
+
}
|
|
3627
|
+
if (Array.isArray(type)) {
|
|
3628
|
+
addArrayType(name, type[0], type[1]);
|
|
3629
|
+
return;
|
|
3630
|
+
}
|
|
3631
|
+
for (const [memberName, memberType] of Object.entries(type)) {
|
|
3632
|
+
addType(`${name}.${memberName}`, memberType);
|
|
3633
|
+
}
|
|
3634
|
+
};
|
|
3635
|
+
const addArrayType = (name, type, arrayLength) => {
|
|
3636
|
+
if (typeof type === "string") {
|
|
3637
|
+
const firstField = fields[`${name}[0]`];
|
|
3638
|
+
const secondField = arrayLength > 1 ? fields[`${name}[1]`] : void 0;
|
|
3639
|
+
if (!firstField) {
|
|
3640
|
+
throw new Error(`Missing std140 array layout field ${name}[0]`);
|
|
3641
|
+
}
|
|
3642
|
+
uniforms.push({
|
|
3643
|
+
name: `${name}[0]`,
|
|
3644
|
+
format: firstField.shaderType,
|
|
3645
|
+
arrayLength,
|
|
3646
|
+
byteOffset: firstField.offset * 4,
|
|
3647
|
+
byteStride: secondField ? (secondField.offset - firstField.offset) * 4 : 0
|
|
3648
|
+
});
|
|
3649
|
+
return;
|
|
3650
|
+
}
|
|
3651
|
+
if (Array.isArray(type)) {
|
|
3652
|
+
throw new Error(`Nested uniform arrays are not supported for ${name}`);
|
|
3653
|
+
}
|
|
3654
|
+
for (const [memberName, memberType] of Object.entries(type)) {
|
|
3655
|
+
if (typeof memberType !== "string") {
|
|
3656
|
+
throw new Error(`Composite uniform array members are not supported for ${name}`);
|
|
3657
|
+
}
|
|
3658
|
+
const firstName = `${name}[0].${memberName}`;
|
|
3659
|
+
const secondName = `${name}[1].${memberName}`;
|
|
3660
|
+
const firstField = fields[firstName];
|
|
3661
|
+
const secondField = arrayLength > 1 ? fields[secondName] : void 0;
|
|
3662
|
+
if (!firstField) {
|
|
3663
|
+
throw new Error(`Missing std140 array layout field ${firstName}`);
|
|
3664
|
+
}
|
|
3665
|
+
uniforms.push({
|
|
3666
|
+
name: firstName,
|
|
3667
|
+
format: firstField.shaderType,
|
|
3668
|
+
arrayLength,
|
|
3669
|
+
byteOffset: firstField.offset * 4,
|
|
3670
|
+
byteStride: secondField ? (secondField.offset - firstField.offset) * 4 : 0
|
|
3671
|
+
});
|
|
3672
|
+
}
|
|
3673
|
+
};
|
|
3674
|
+
for (const [uniformName, uniformType] of Object.entries(uniformTypes)) {
|
|
3675
|
+
addType(uniformName, uniformType);
|
|
3676
|
+
}
|
|
3677
|
+
return uniforms;
|
|
3678
|
+
}
|
|
3679
|
+
function isUsableUniformBlockBinding(binding) {
|
|
3680
|
+
return binding.type === "uniform" && Number.isInteger(binding.minBindingSize) && binding.minBindingSize >= 0 && Array.isArray(binding.uniforms) && binding.uniforms.every((uniform) => typeof uniform.name === "string" && typeof uniform.format === "string" && Number.isInteger(uniform.arrayLength) && uniform.arrayLength > 0 && Number.isInteger(uniform.byteOffset) && uniform.byteOffset >= 0 && Number.isInteger(uniform.byteStride) && uniform.byteStride >= 0);
|
|
3681
|
+
}
|
|
3682
|
+
function parseUniformName(name) {
|
|
3683
|
+
if (name[name.length - 1] !== "]") {
|
|
3684
|
+
return {
|
|
3685
|
+
name,
|
|
3686
|
+
length: 1,
|
|
3687
|
+
isArray: false
|
|
3688
|
+
};
|
|
3689
|
+
}
|
|
3690
|
+
const UNIFORM_NAME_REGEXP = /([^[]*)(\[[0-9]+\])?/;
|
|
3691
|
+
const matches = UNIFORM_NAME_REGEXP.exec(name);
|
|
3692
|
+
const uniformName = (0, import_core15.assertDefined)(matches?.[1], `Failed to parse GLSL uniform name ${name}`);
|
|
3693
|
+
return {
|
|
3694
|
+
name: uniformName,
|
|
3695
|
+
// TODO - is this a bug, shouldn't we return the value?
|
|
3696
|
+
length: matches?.[2] ? 1 : 0,
|
|
3697
|
+
isArray: Boolean(matches?.[2])
|
|
3698
|
+
};
|
|
3699
|
+
}
|
|
3700
|
+
var import_core15;
|
|
3701
|
+
var init_get_shader_layout_from_glsl = __esm({
|
|
3702
|
+
"../../node_modules/@luma.gl/webgl/dist/adapter/helpers/get-shader-layout-from-glsl.js"() {
|
|
3703
|
+
import_core15 = __toESM(require_core2(), 1);
|
|
3704
|
+
init_webgl_shadertypes();
|
|
3705
|
+
}
|
|
3706
|
+
});
|
|
3707
|
+
|
|
3708
|
+
// ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-render-pipeline.js
|
|
3709
|
+
function mergeShaderLayout(baseLayout, overrideLayout) {
|
|
3710
|
+
const mergedLayout = {
|
|
3711
|
+
...baseLayout,
|
|
3712
|
+
attributes: baseLayout.attributes.map((attribute) => ({ ...attribute })),
|
|
3713
|
+
bindings: baseLayout.bindings.map((binding) => ({ ...binding }))
|
|
3714
|
+
};
|
|
3715
|
+
for (const attribute of overrideLayout?.attributes || []) {
|
|
3716
|
+
const baseAttribute = mergedLayout.attributes.find((attr) => attr.name === attribute.name);
|
|
3717
|
+
if (!baseAttribute) {
|
|
3718
|
+
import_core16.log.warn(`shader layout attribute ${attribute.name} not present in shader`);
|
|
3719
|
+
} else {
|
|
3720
|
+
baseAttribute.type = attribute.type || baseAttribute.type;
|
|
3721
|
+
baseAttribute.stepMode = attribute.stepMode || baseAttribute.stepMode;
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
for (const binding of overrideLayout?.bindings || []) {
|
|
3725
|
+
const baseBinding = getShaderLayoutBindingByName(mergedLayout, binding.name);
|
|
3726
|
+
if (!baseBinding) {
|
|
3727
|
+
import_core16.log.warn(`shader layout binding ${binding.name} not present in shader`);
|
|
3728
|
+
continue;
|
|
3729
|
+
}
|
|
3730
|
+
Object.assign(baseBinding, binding);
|
|
3731
|
+
}
|
|
3732
|
+
return mergedLayout;
|
|
3733
|
+
}
|
|
3734
|
+
function getShaderLayoutBindingByName(shaderLayout, bindingName) {
|
|
3735
|
+
return shaderLayout.bindings.find((binding) => binding.name === bindingName || binding.name === `${bindingName}Uniforms` || `${binding.name}Uniforms` === bindingName);
|
|
3736
|
+
}
|
|
3737
|
+
function getBindingValueForLayoutBinding(bindings, bindingName) {
|
|
3738
|
+
return bindings[bindingName] || bindings[`${bindingName}Uniforms`] || bindings[bindingName.replace(/Uniforms$/, "")];
|
|
3739
|
+
}
|
|
3740
|
+
var import_core16, WEBGLRenderPipeline;
|
|
3741
|
+
var init_webgl_render_pipeline = __esm({
|
|
3742
|
+
"../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-render-pipeline.js"() {
|
|
3743
|
+
import_core16 = __toESM(require_core2(), 1);
|
|
3744
|
+
init_set_uniform();
|
|
3745
|
+
init_webgl_buffer();
|
|
3746
|
+
init_webgl_framebuffer();
|
|
3747
|
+
init_webgl_texture();
|
|
3748
|
+
init_webgl_texture_view();
|
|
3749
|
+
init_get_shader_layout_from_glsl();
|
|
3750
|
+
WEBGLRenderPipeline = class extends import_core16.RenderPipeline {
|
|
3751
|
+
/** The WebGL device that created this render pipeline */
|
|
3752
|
+
device;
|
|
3753
|
+
/** Handle to underlying WebGL program */
|
|
3754
|
+
handle;
|
|
3755
|
+
/** vertex shader */
|
|
3756
|
+
vs;
|
|
3757
|
+
/** fragment shader */
|
|
3758
|
+
fs;
|
|
3759
|
+
/** The layout extracted from shader by WebGL introspection APIs */
|
|
3760
|
+
introspectedLayout;
|
|
3761
|
+
/** Compatibility path for direct pipeline.setBindings() usage */
|
|
3762
|
+
bindings = {};
|
|
3763
|
+
/** Compatibility path for direct pipeline.uniforms usage */
|
|
3764
|
+
uniforms = {};
|
|
3765
|
+
/** WebGL varyings */
|
|
3766
|
+
varyings = null;
|
|
3767
|
+
_uniformCount = 0;
|
|
3768
|
+
_uniformSetters = {};
|
|
3769
|
+
// TODO are these used?
|
|
3770
|
+
get [Symbol.toStringTag]() {
|
|
3771
|
+
return "WEBGLRenderPipeline";
|
|
3772
|
+
}
|
|
3773
|
+
constructor(device, props) {
|
|
3774
|
+
super(device, props);
|
|
3775
|
+
this.device = device;
|
|
3776
|
+
const webglSharedRenderPipeline = this.sharedRenderPipeline || this.device._createSharedRenderPipelineWebGL(props);
|
|
3777
|
+
this.sharedRenderPipeline = webglSharedRenderPipeline;
|
|
3778
|
+
this.handle = webglSharedRenderPipeline.handle;
|
|
3779
|
+
this.vs = webglSharedRenderPipeline.vs;
|
|
3780
|
+
this.fs = webglSharedRenderPipeline.fs;
|
|
3781
|
+
this.linkStatus = webglSharedRenderPipeline.linkStatus;
|
|
3782
|
+
this.introspectedLayout = getShaderLayoutFromGLSL(this.device.gl, this.handle, {
|
|
3783
|
+
uniformBlockLayouts: props._uniformBlockLayouts,
|
|
3784
|
+
shaderLayout: props.shaderLayout
|
|
3785
|
+
});
|
|
3786
|
+
this.device._setWebGLDebugMetadata(this.handle, this, { spector: { id: this.props.id } });
|
|
3787
|
+
this.shaderLayout = props.shaderLayout ? mergeShaderLayout(this.introspectedLayout, props.shaderLayout) : this.introspectedLayout;
|
|
3788
|
+
}
|
|
3789
|
+
destroy() {
|
|
3790
|
+
if (this.destroyed) {
|
|
3791
|
+
return;
|
|
3792
|
+
}
|
|
3793
|
+
if (this.sharedRenderPipeline && !this.props._sharedRenderPipeline) {
|
|
3794
|
+
this.sharedRenderPipeline.destroy();
|
|
3795
|
+
}
|
|
3796
|
+
this.destroyResource();
|
|
3797
|
+
}
|
|
3798
|
+
/** @deprecated Set bindings on RenderPass instead. Will be removed in the next major release. */
|
|
3799
|
+
setBindings(bindings, options) {
|
|
3800
|
+
const flatBindings = (0, import_core16.flattenBindingsByGroup)((0, import_core16.normalizeBindingsByGroup)(this.shaderLayout, bindings));
|
|
3801
|
+
for (const [name, value] of Object.entries(flatBindings)) {
|
|
3802
|
+
const binding = getShaderLayoutBindingByName(this.shaderLayout, name);
|
|
3803
|
+
if (!binding) {
|
|
3804
|
+
const validBindings = this.shaderLayout.bindings.map((binding_) => `"${binding_.name}"`).join(", ");
|
|
3805
|
+
if (!options?.disableWarnings) {
|
|
3806
|
+
import_core16.log.warn(`No binding "${name}" in render pipeline "${this.id}", expected one of ${validBindings}`, value)();
|
|
3807
|
+
}
|
|
3808
|
+
} else {
|
|
3809
|
+
if (!value) {
|
|
3810
|
+
import_core16.log.warn(`Unsetting binding "${name}" in render pipeline "${this.id}"`)();
|
|
3811
|
+
}
|
|
3812
|
+
switch (binding.type) {
|
|
3813
|
+
case "uniform":
|
|
3814
|
+
if (!(value instanceof WEBGLBuffer) && !(value.buffer instanceof WEBGLBuffer)) {
|
|
3815
|
+
throw new Error("buffer value");
|
|
3816
|
+
}
|
|
3817
|
+
break;
|
|
3818
|
+
case "texture":
|
|
3819
|
+
if (!(value instanceof WEBGLTextureView || value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
|
|
3820
|
+
throw new Error(`${this} Bad texture binding for ${name}`);
|
|
3821
|
+
}
|
|
3822
|
+
break;
|
|
3823
|
+
case "sampler":
|
|
3824
|
+
import_core16.log.warn(`Ignoring sampler ${name}`)();
|
|
3825
|
+
break;
|
|
3826
|
+
default:
|
|
3827
|
+
throw new Error(binding.type);
|
|
3828
|
+
}
|
|
3829
|
+
this.bindings[name] = value;
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
}
|
|
3833
|
+
/** @todo needed for portable model
|
|
3834
|
+
* @note The WebGL API is offers many ways to draw things
|
|
3835
|
+
* This function unifies those ways into a single call using common parameters with sane defaults
|
|
3836
|
+
*/
|
|
3837
|
+
draw(options) {
|
|
3838
|
+
const webglRenderPass = options.renderPass;
|
|
3839
|
+
const drawBindings = options.bindGroups ? (0, import_core16.flattenBindingsByGroup)(options.bindGroups) : options.bindings || this.bindings;
|
|
3840
|
+
webglRenderPass.setPipeline(this);
|
|
3841
|
+
webglRenderPass.setBindings(drawBindings);
|
|
3842
|
+
webglRenderPass.setVertexArray(options.vertexArray);
|
|
3843
|
+
return webglRenderPass.draw({
|
|
3844
|
+
parameters: options.parameters,
|
|
3845
|
+
topology: options.topology,
|
|
3846
|
+
isInstanced: options.isInstanced,
|
|
3847
|
+
vertexCount: options.vertexCount,
|
|
3848
|
+
indexCount: options.indexCount,
|
|
3849
|
+
instanceCount: options.instanceCount,
|
|
3850
|
+
firstVertex: options.firstVertex,
|
|
3851
|
+
firstIndex: options.firstIndex,
|
|
3852
|
+
firstInstance: options.firstInstance,
|
|
3853
|
+
baseVertex: options.baseVertex,
|
|
3854
|
+
transformFeedback: options.transformFeedback,
|
|
3855
|
+
uniforms: options.uniforms
|
|
3704
3856
|
});
|
|
3705
3857
|
}
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3858
|
+
/**
|
|
3859
|
+
* Checks if all texture-values uniforms are renderable (i.e. loaded)
|
|
3860
|
+
* Update a texture if needed (e.g. from video)
|
|
3861
|
+
* Note: This is currently done before every draw call
|
|
3862
|
+
*/
|
|
3863
|
+
_areTexturesRenderable(bindings) {
|
|
3864
|
+
let texturesRenderable = true;
|
|
3865
|
+
for (const bindingInfo of this.shaderLayout.bindings) {
|
|
3866
|
+
if (!getBindingValueForLayoutBinding(bindings, bindingInfo.name)) {
|
|
3867
|
+
import_core16.log.warn(`Binding ${bindingInfo.name} not found in ${this.id}`)();
|
|
3868
|
+
texturesRenderable = false;
|
|
3869
|
+
}
|
|
3870
|
+
}
|
|
3871
|
+
return texturesRenderable;
|
|
3872
|
+
}
|
|
3873
|
+
/** Apply any bindings (before each draw call) */
|
|
3874
|
+
_applyBindings(bindings, _options) {
|
|
3875
|
+
this._syncLinkStatus();
|
|
3876
|
+
if (this.linkStatus !== "success") {
|
|
3877
|
+
return;
|
|
3878
|
+
}
|
|
3879
|
+
const { gl } = this.device;
|
|
3880
|
+
gl.useProgram(this.handle);
|
|
3881
|
+
let textureUnit = 0;
|
|
3882
|
+
let uniformBufferIndex = 0;
|
|
3883
|
+
for (const binding of this.shaderLayout.bindings) {
|
|
3884
|
+
const value = getBindingValueForLayoutBinding(bindings, binding.name);
|
|
3885
|
+
if (!value) {
|
|
3886
|
+
throw new Error(`No value for binding ${binding.name} in ${this.id}`);
|
|
3887
|
+
}
|
|
3888
|
+
switch (binding.type) {
|
|
3889
|
+
case "uniform":
|
|
3890
|
+
const { name } = binding;
|
|
3891
|
+
const location = gl.getUniformBlockIndex(this.handle, name);
|
|
3892
|
+
if (location === 4294967295) {
|
|
3893
|
+
throw new Error(`Invalid uniform block name ${name}`);
|
|
3894
|
+
}
|
|
3895
|
+
gl.uniformBlockBinding(this.handle, location, uniformBufferIndex);
|
|
3896
|
+
if (value instanceof WEBGLBuffer) {
|
|
3897
|
+
gl.bindBufferBase(35345, uniformBufferIndex, value.handle);
|
|
3898
|
+
} else {
|
|
3899
|
+
const bufferBinding = value;
|
|
3900
|
+
gl.bindBufferRange(35345, uniformBufferIndex, bufferBinding.buffer.handle, bufferBinding.offset || 0, bufferBinding.size || bufferBinding.buffer.byteLength - (bufferBinding.offset || 0));
|
|
3901
|
+
}
|
|
3902
|
+
uniformBufferIndex += 1;
|
|
3903
|
+
break;
|
|
3904
|
+
case "texture":
|
|
3905
|
+
if (!(value instanceof WEBGLTextureView || value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
|
|
3906
|
+
throw new Error("texture");
|
|
3907
|
+
}
|
|
3908
|
+
let texture;
|
|
3909
|
+
if (value instanceof WEBGLTextureView) {
|
|
3910
|
+
texture = value.texture;
|
|
3911
|
+
} else if (value instanceof WEBGLTexture) {
|
|
3912
|
+
texture = value;
|
|
3913
|
+
} else if (value instanceof WEBGLFramebuffer && value.colorAttachments[0] instanceof WEBGLTextureView) {
|
|
3914
|
+
import_core16.log.warn("Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead")();
|
|
3915
|
+
texture = value.colorAttachments[0].texture;
|
|
3916
|
+
} else {
|
|
3917
|
+
throw new Error("No texture");
|
|
3918
|
+
}
|
|
3919
|
+
gl.activeTexture(33984 + textureUnit);
|
|
3920
|
+
gl.bindTexture(texture.glTarget, texture.handle);
|
|
3921
|
+
textureUnit += 1;
|
|
3922
|
+
break;
|
|
3923
|
+
case "sampler":
|
|
3924
|
+
break;
|
|
3925
|
+
case "storage":
|
|
3926
|
+
case "read-only-storage":
|
|
3927
|
+
throw new Error(`binding type '${binding.type}' not supported in WebGL`);
|
|
3928
|
+
}
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
/**
|
|
3932
|
+
* Due to program sharing, uniforms need to be reset before every draw call
|
|
3933
|
+
* (though caching will avoid redundant WebGL calls)
|
|
3934
|
+
*/
|
|
3935
|
+
_applyUniforms(uniforms) {
|
|
3936
|
+
for (const uniformLayout of this.shaderLayout.uniforms || []) {
|
|
3937
|
+
const { name, location, type, textureUnit } = uniformLayout;
|
|
3938
|
+
const value = uniforms[name] ?? textureUnit;
|
|
3939
|
+
if (value !== void 0) {
|
|
3940
|
+
setUniform(this.device.gl, location, type, value);
|
|
3941
|
+
}
|
|
3942
|
+
}
|
|
3943
|
+
}
|
|
3944
|
+
_syncLinkStatus() {
|
|
3945
|
+
this.linkStatus = this.sharedRenderPipeline.linkStatus;
|
|
3946
|
+
}
|
|
3724
3947
|
};
|
|
3725
3948
|
}
|
|
3726
|
-
const UNIFORM_NAME_REGEXP = /([^[]*)(\[[0-9]+\])?/;
|
|
3727
|
-
const matches = UNIFORM_NAME_REGEXP.exec(name);
|
|
3728
|
-
const uniformName = (0, import_core16.assertDefined)(matches?.[1], `Failed to parse GLSL uniform name ${name}`);
|
|
3729
|
-
return {
|
|
3730
|
-
name: uniformName,
|
|
3731
|
-
// TODO - is this a bug, shouldn't we return the value?
|
|
3732
|
-
length: matches?.[2] ? 1 : 0,
|
|
3733
|
-
isArray: Boolean(matches?.[2])
|
|
3734
|
-
};
|
|
3735
|
-
}
|
|
3736
|
-
var import_core16;
|
|
3737
|
-
var init_get_shader_layout_from_glsl = __esm({
|
|
3738
|
-
"../../node_modules/@luma.gl/webgl/dist/adapter/helpers/get-shader-layout-from-glsl.js"() {
|
|
3739
|
-
import_core16 = __toESM(require_core2(), 1);
|
|
3740
|
-
init_webgl_shadertypes();
|
|
3741
|
-
}
|
|
3742
3949
|
});
|
|
3743
3950
|
|
|
3744
3951
|
// ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-shared-render-pipeline.js
|
|
@@ -3746,7 +3953,6 @@ Source: ${sourceLine}` : "";
|
|
|
3746
3953
|
var init_webgl_shared_render_pipeline = __esm({
|
|
3747
3954
|
"../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-shared-render-pipeline.js"() {
|
|
3748
3955
|
import_core17 = __toESM(require_core2(), 1);
|
|
3749
|
-
init_get_shader_layout_from_glsl();
|
|
3750
3956
|
init_webgl_shadertypes();
|
|
3751
3957
|
LOG_PROGRAM_PERF_PRIORITY = 4;
|
|
3752
3958
|
WEBGLSharedRenderPipeline = class extends import_core17.SharedRenderPipeline {
|
|
@@ -3754,7 +3960,6 @@ Source: ${sourceLine}` : "";
|
|
|
3754
3960
|
handle;
|
|
3755
3961
|
vs;
|
|
3756
3962
|
fs;
|
|
3757
|
-
introspectedLayout = { attributes: [], bindings: [], uniforms: [] };
|
|
3758
3963
|
linkStatus = "pending";
|
|
3759
3964
|
constructor(device, props) {
|
|
3760
3965
|
super(device, props);
|
|
@@ -3766,9 +3971,6 @@ Source: ${sourceLine}` : "";
|
|
|
3766
3971
|
this.device.gl.transformFeedbackVaryings(this.handle, props.varyings, props.bufferMode || 35981);
|
|
3767
3972
|
}
|
|
3768
3973
|
this._linkShaders();
|
|
3769
|
-
import_core17.log.time(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
|
|
3770
|
-
this.introspectedLayout = getShaderLayoutFromGLSL(this.device.gl, this.handle);
|
|
3771
|
-
import_core17.log.timeEnd(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
|
|
3772
3974
|
}
|
|
3773
3975
|
destroy() {
|
|
3774
3976
|
if (this.destroyed) {
|
|
@@ -11463,8 +11665,8 @@ void main(void) {
|
|
|
11463
11665
|
}
|
|
11464
11666
|
return PROJECTION_MODE.IDENTITY;
|
|
11465
11667
|
}
|
|
11466
|
-
// Two viewports are equal if
|
|
11467
|
-
//
|
|
11668
|
+
// Two viewports are equal if their dimensions, common-space scale, and
|
|
11669
|
+
// view and projection matrices are (approximately) equal.
|
|
11468
11670
|
equals(viewport) {
|
|
11469
11671
|
if (!(viewport instanceof _Viewport)) {
|
|
11470
11672
|
return false;
|
|
@@ -11472,7 +11674,7 @@ void main(void) {
|
|
|
11472
11674
|
if (this === viewport) {
|
|
11473
11675
|
return true;
|
|
11474
11676
|
}
|
|
11475
|
-
return viewport.width === this.width && viewport.height === this.height && viewport.scale === this.scale && equals(viewport.projectionMatrix, this.projectionMatrix) && equals(viewport.viewMatrix, this.viewMatrix);
|
|
11677
|
+
return viewport.width === this.width && viewport.height === this.height && viewport.scale === this.scale && viewport.projectionMode === this.projectionMode && viewport.resolution === this.resolution && equals(viewport.distanceScales.unitsPerMeter, this.distanceScales.unitsPerMeter) && equals(viewport.projectionMatrix, this.projectionMatrix) && equals(viewport.viewMatrix, this.viewMatrix);
|
|
11476
11678
|
}
|
|
11477
11679
|
/**
|
|
11478
11680
|
* Projects xyz (possibly latitude and longitude) to pixel coordinates in window
|
|
@@ -11807,6 +12009,10 @@ void main(void) {
|
|
|
11807
12009
|
}
|
|
11808
12010
|
return this._subViewports;
|
|
11809
12011
|
}
|
|
12012
|
+
/** Returns whether two Web Mercator viewports use the same projection settings. */
|
|
12013
|
+
equals(viewport) {
|
|
12014
|
+
return viewport instanceof _WebMercatorViewport && viewport._pseudoMeters === this._pseudoMeters && super.equals(viewport);
|
|
12015
|
+
}
|
|
11810
12016
|
projectPosition(xyz) {
|
|
11811
12017
|
if (this._pseudoMeters) {
|
|
11812
12018
|
return super.projectPosition(xyz);
|
|
@@ -12177,178 +12383,6 @@ void main(void) {
|
|
|
12177
12383
|
}
|
|
12178
12384
|
};
|
|
12179
12385
|
|
|
12180
|
-
// ../core/src/viewports/globe-viewport.ts
|
|
12181
|
-
var DEGREES_TO_RADIANS5 = Math.PI / 180;
|
|
12182
|
-
var RADIANS_TO_DEGREES3 = 180 / Math.PI;
|
|
12183
|
-
var EARTH_RADIUS = 6370972;
|
|
12184
|
-
var GLOBE_RADIUS = 256;
|
|
12185
|
-
function getDistanceScales2() {
|
|
12186
|
-
const unitsPerMeter2 = GLOBE_RADIUS / EARTH_RADIUS;
|
|
12187
|
-
const unitsPerDegree = Math.PI / 180 * GLOBE_RADIUS;
|
|
12188
|
-
return {
|
|
12189
|
-
unitsPerMeter: [unitsPerMeter2, unitsPerMeter2, unitsPerMeter2],
|
|
12190
|
-
unitsPerMeter2: [0, 0, 0],
|
|
12191
|
-
metersPerUnit: [1 / unitsPerMeter2, 1 / unitsPerMeter2, 1 / unitsPerMeter2],
|
|
12192
|
-
unitsPerDegree: [unitsPerDegree, unitsPerDegree, unitsPerMeter2],
|
|
12193
|
-
unitsPerDegree2: [0, 0, 0],
|
|
12194
|
-
degreesPerUnit: [1 / unitsPerDegree, 1 / unitsPerDegree, 1 / unitsPerMeter2]
|
|
12195
|
-
};
|
|
12196
|
-
}
|
|
12197
|
-
var GlobeViewport = class extends Viewport {
|
|
12198
|
-
constructor(opts = {}) {
|
|
12199
|
-
const {
|
|
12200
|
-
longitude = 0,
|
|
12201
|
-
bearing = 0,
|
|
12202
|
-
pitch = 0,
|
|
12203
|
-
zoom = 0,
|
|
12204
|
-
// Matches Maplibre defaults
|
|
12205
|
-
// https://github.com/maplibre/maplibre-gl-js/blob/f8ab4b48d59ab8fe7b068b102538793bbdd4c848/src/geo/projection/globe_transform.ts#L632-L633
|
|
12206
|
-
nearZMultiplier = 0.5,
|
|
12207
|
-
farZMultiplier = 1,
|
|
12208
|
-
resolution = 10
|
|
12209
|
-
} = opts;
|
|
12210
|
-
let { latitude = 0, height, altitude = 1.5, fovy } = opts;
|
|
12211
|
-
latitude = Math.max(Math.min(latitude, 90), -90);
|
|
12212
|
-
height = height || 1;
|
|
12213
|
-
if (fovy) {
|
|
12214
|
-
altitude = fovyToAltitude(fovy);
|
|
12215
|
-
} else {
|
|
12216
|
-
fovy = altitudeToFovy(altitude);
|
|
12217
|
-
}
|
|
12218
|
-
const scaleLatitude = Math.max(Math.min(latitude, MAX_LATITUDE), -MAX_LATITUDE);
|
|
12219
|
-
const scale5 = Math.pow(2, zoom - zoomAdjust(scaleLatitude));
|
|
12220
|
-
const pitchRadians = pitch * DEGREES_TO_RADIANS5;
|
|
12221
|
-
const nearZ = opts.nearZ ?? nearZMultiplier;
|
|
12222
|
-
const farZ = opts.farZ ?? (altitude + GLOBE_RADIUS * 2 * scale5 / height / Math.max(Math.cos(pitchRadians), 0.1)) * farZMultiplier;
|
|
12223
|
-
const viewMatrix = new Matrix4().lookAt({ eye: [0, -altitude, 0], up: [0, 0, 1] }).rotateX(-pitchRadians).rotateY(-bearing * DEGREES_TO_RADIANS5).rotateX(latitude * DEGREES_TO_RADIANS5).rotateZ(-longitude * DEGREES_TO_RADIANS5).scale(scale5 / height);
|
|
12224
|
-
super({
|
|
12225
|
-
...opts,
|
|
12226
|
-
// x, y, width,
|
|
12227
|
-
height,
|
|
12228
|
-
// view matrix
|
|
12229
|
-
viewMatrix,
|
|
12230
|
-
longitude,
|
|
12231
|
-
latitude,
|
|
12232
|
-
zoom,
|
|
12233
|
-
// projection matrix parameters
|
|
12234
|
-
distanceScales: getDistanceScales2(),
|
|
12235
|
-
fovy,
|
|
12236
|
-
focalDistance: altitude,
|
|
12237
|
-
near: nearZ,
|
|
12238
|
-
far: farZ
|
|
12239
|
-
});
|
|
12240
|
-
this.scale = scale5;
|
|
12241
|
-
this.latitude = latitude;
|
|
12242
|
-
this.longitude = longitude;
|
|
12243
|
-
this.bearing = bearing;
|
|
12244
|
-
this.pitch = pitch;
|
|
12245
|
-
this.fovy = fovy;
|
|
12246
|
-
this.resolution = resolution;
|
|
12247
|
-
}
|
|
12248
|
-
get projectionMode() {
|
|
12249
|
-
return PROJECTION_MODE.GLOBE;
|
|
12250
|
-
}
|
|
12251
|
-
getDistanceScales() {
|
|
12252
|
-
return this.distanceScales;
|
|
12253
|
-
}
|
|
12254
|
-
getBounds(options = {}) {
|
|
12255
|
-
const unprojectOption = { targetZ: options.z || 0 };
|
|
12256
|
-
const left = this.unproject([0, this.height / 2], unprojectOption);
|
|
12257
|
-
const top = this.unproject([this.width / 2, 0], unprojectOption);
|
|
12258
|
-
const right = this.unproject([this.width, this.height / 2], unprojectOption);
|
|
12259
|
-
const bottom = this.unproject([this.width / 2, this.height], unprojectOption);
|
|
12260
|
-
if (right[0] < this.longitude) right[0] += 360;
|
|
12261
|
-
if (left[0] > this.longitude) left[0] -= 360;
|
|
12262
|
-
return [
|
|
12263
|
-
Math.min(left[0], right[0], top[0], bottom[0]),
|
|
12264
|
-
Math.min(left[1], right[1], top[1], bottom[1]),
|
|
12265
|
-
Math.max(left[0], right[0], top[0], bottom[0]),
|
|
12266
|
-
Math.max(left[1], right[1], top[1], bottom[1])
|
|
12267
|
-
];
|
|
12268
|
-
}
|
|
12269
|
-
unproject(xyz, { topLeft = true, targetZ } = {}) {
|
|
12270
|
-
const [x, y, z] = xyz;
|
|
12271
|
-
const y2 = topLeft ? y : this.height - y;
|
|
12272
|
-
const { pixelUnprojectionMatrix } = this;
|
|
12273
|
-
let coord;
|
|
12274
|
-
if (Number.isFinite(z)) {
|
|
12275
|
-
coord = transformVector2(pixelUnprojectionMatrix, [x, y2, z, 1]);
|
|
12276
|
-
} else {
|
|
12277
|
-
const coord0 = transformVector2(pixelUnprojectionMatrix, [x, y2, -1, 1]);
|
|
12278
|
-
const coord1 = transformVector2(pixelUnprojectionMatrix, [x, y2, 1, 1]);
|
|
12279
|
-
const lt = ((targetZ || 0) / EARTH_RADIUS + 1) * GLOBE_RADIUS;
|
|
12280
|
-
const lSqr = vec3_exports.sqrLen(vec3_exports.sub([], coord0, coord1));
|
|
12281
|
-
const l0Sqr = vec3_exports.sqrLen(coord0);
|
|
12282
|
-
const l1Sqr = vec3_exports.sqrLen(coord1);
|
|
12283
|
-
const sSqr = (4 * l0Sqr * l1Sqr - (lSqr - l0Sqr - l1Sqr) ** 2) / 16;
|
|
12284
|
-
const dSqr = 4 * sSqr / lSqr;
|
|
12285
|
-
const r0 = Math.sqrt(l0Sqr - dSqr);
|
|
12286
|
-
const dr = Math.sqrt(Math.max(0, lt * lt - dSqr));
|
|
12287
|
-
const t = (r0 - dr) / Math.sqrt(lSqr);
|
|
12288
|
-
coord = vec3_exports.lerp([], coord0, coord1, t);
|
|
12289
|
-
}
|
|
12290
|
-
const [X, Y, Z] = this.unprojectPosition(coord);
|
|
12291
|
-
if (Number.isFinite(z)) {
|
|
12292
|
-
return [X, Y, Z];
|
|
12293
|
-
}
|
|
12294
|
-
return Number.isFinite(targetZ) ? [X, Y, targetZ] : [X, Y];
|
|
12295
|
-
}
|
|
12296
|
-
projectPosition(xyz) {
|
|
12297
|
-
const [lng, lat, Z = 0] = xyz;
|
|
12298
|
-
const lambda = lng * DEGREES_TO_RADIANS5;
|
|
12299
|
-
const phi = lat * DEGREES_TO_RADIANS5;
|
|
12300
|
-
const cosPhi = Math.cos(phi);
|
|
12301
|
-
const D = (Z / EARTH_RADIUS + 1) * GLOBE_RADIUS;
|
|
12302
|
-
return [Math.sin(lambda) * cosPhi * D, -Math.cos(lambda) * cosPhi * D, Math.sin(phi) * D];
|
|
12303
|
-
}
|
|
12304
|
-
unprojectPosition(xyz) {
|
|
12305
|
-
const [x, y, z] = xyz;
|
|
12306
|
-
const D = vec3_exports.len(xyz);
|
|
12307
|
-
const phi = Math.asin(z / D);
|
|
12308
|
-
const lambda = Math.atan2(x, -y);
|
|
12309
|
-
const lng = lambda * RADIANS_TO_DEGREES3;
|
|
12310
|
-
const lat = phi * RADIANS_TO_DEGREES3;
|
|
12311
|
-
const Z = (D / GLOBE_RADIUS - 1) * EARTH_RADIUS;
|
|
12312
|
-
return [lng, lat, Z];
|
|
12313
|
-
}
|
|
12314
|
-
projectFlat(xyz) {
|
|
12315
|
-
return xyz;
|
|
12316
|
-
}
|
|
12317
|
-
unprojectFlat(xyz) {
|
|
12318
|
-
return xyz;
|
|
12319
|
-
}
|
|
12320
|
-
/**
|
|
12321
|
-
* Pan the globe using delta-based movement
|
|
12322
|
-
* @param coords - the geographic coordinates where the pan started
|
|
12323
|
-
* @param pixel - the current screen position
|
|
12324
|
-
* @param startPixel - the screen position where the pan started
|
|
12325
|
-
* @returns updated viewport options with new longitude/latitude
|
|
12326
|
-
*/
|
|
12327
|
-
panByPosition([startLng, startLat, startZoom], pixel, startPixel) {
|
|
12328
|
-
const scale5 = Math.pow(2, this.zoom - zoomAdjust(this.latitude));
|
|
12329
|
-
const rotationSpeed = 0.25 / scale5;
|
|
12330
|
-
const longitude = startLng + rotationSpeed * (startPixel[0] - pixel[0]);
|
|
12331
|
-
let latitude = startLat - rotationSpeed * (startPixel[1] - pixel[1]);
|
|
12332
|
-
latitude = Math.max(Math.min(latitude, 90), -90);
|
|
12333
|
-
const out = { longitude, latitude, zoom: startZoom - zoomAdjust(startLat) };
|
|
12334
|
-
out.zoom += zoomAdjust(out.latitude);
|
|
12335
|
-
return out;
|
|
12336
|
-
}
|
|
12337
|
-
};
|
|
12338
|
-
GlobeViewport.displayName = "GlobeViewport";
|
|
12339
|
-
function zoomAdjust(latitude, clampToPoles) {
|
|
12340
|
-
if (clampToPoles) {
|
|
12341
|
-
latitude = Math.max(Math.min(latitude, MAX_LATITUDE), -MAX_LATITUDE);
|
|
12342
|
-
}
|
|
12343
|
-
const scaleAdjust = Math.PI * Math.cos(latitude * Math.PI / 180);
|
|
12344
|
-
return Math.log2(scaleAdjust);
|
|
12345
|
-
}
|
|
12346
|
-
function transformVector2(matrix, vector) {
|
|
12347
|
-
const result = vec4_exports.transformMat4([], vector, matrix);
|
|
12348
|
-
vec4_exports.scale(result, result, 1 / result[3]);
|
|
12349
|
-
return result;
|
|
12350
|
-
}
|
|
12351
|
-
|
|
12352
12386
|
// ../core/src/transitions/linear-interpolator.ts
|
|
12353
12387
|
var DEFAULT_PROPS = ["longitude", "latitude", "zoom", "bearing", "pitch"];
|
|
12354
12388
|
var DEFAULT_REQUIRED_PROPS = ["longitude", "latitude", "zoom"];
|
|
@@ -12376,21 +12410,16 @@ void main(void) {
|
|
|
12376
12410
|
const result = super.initializeProps(startProps, endProps);
|
|
12377
12411
|
const { makeViewport, around } = this.opts;
|
|
12378
12412
|
if (makeViewport && around) {
|
|
12379
|
-
const
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
aroundPosition,
|
|
12390
|
-
width: endProps.width,
|
|
12391
|
-
height: endProps.height
|
|
12392
|
-
});
|
|
12393
|
-
}
|
|
12413
|
+
const startViewport = makeViewport(startProps);
|
|
12414
|
+
const endViewport = makeViewport(endProps);
|
|
12415
|
+
const aroundPosition = startViewport.unproject(around);
|
|
12416
|
+
result.start.around = around;
|
|
12417
|
+
Object.assign(result.end, {
|
|
12418
|
+
around: endViewport.project(aroundPosition),
|
|
12419
|
+
aroundPosition,
|
|
12420
|
+
width: endProps.width,
|
|
12421
|
+
height: endProps.height
|
|
12422
|
+
});
|
|
12394
12423
|
}
|
|
12395
12424
|
return result;
|
|
12396
12425
|
}
|
|
@@ -12463,6 +12492,7 @@ void main(void) {
|
|
|
12463
12492
|
this.touchRotate = false;
|
|
12464
12493
|
this.multiTouchDrag = null;
|
|
12465
12494
|
this.trackpadGesture = false;
|
|
12495
|
+
this.zoomAround = "pointer";
|
|
12466
12496
|
this.keyboard = true;
|
|
12467
12497
|
this.transitionManager = new TransitionManager({
|
|
12468
12498
|
...opts,
|
|
@@ -12556,6 +12586,15 @@ void main(void) {
|
|
|
12556
12586
|
const { offsetCenter } = event;
|
|
12557
12587
|
return [offsetCenter.x - x, offsetCenter.y - y];
|
|
12558
12588
|
}
|
|
12589
|
+
/** Resolves the zoom anchor for pointer-based controls. */
|
|
12590
|
+
getZoomPosition(position) {
|
|
12591
|
+
if (this.zoomAround === "pointer") {
|
|
12592
|
+
return position;
|
|
12593
|
+
}
|
|
12594
|
+
const viewport = this.makeViewport(this.controllerState.getViewportProps());
|
|
12595
|
+
const [centerX, centerY] = worldToPixels(viewport.center, viewport.pixelProjectionMatrix);
|
|
12596
|
+
return [centerX, centerY];
|
|
12597
|
+
}
|
|
12559
12598
|
isPointInBounds(pos, event) {
|
|
12560
12599
|
const { width, height } = this.props;
|
|
12561
12600
|
if (event && event.handled) {
|
|
@@ -12613,6 +12652,7 @@ void main(void) {
|
|
|
12613
12652
|
touchRotate = false,
|
|
12614
12653
|
multiTouchDrag = touchRotate ? "rotate" : null,
|
|
12615
12654
|
trackpadGesture = false,
|
|
12655
|
+
zoomAround = "pointer",
|
|
12616
12656
|
keyboard = true
|
|
12617
12657
|
} = props;
|
|
12618
12658
|
const isInteractive = Boolean(this.onViewStateChange);
|
|
@@ -12635,6 +12675,7 @@ void main(void) {
|
|
|
12635
12675
|
this.touchRotate = multiTouchDrag === "rotate";
|
|
12636
12676
|
this.multiTouchDrag = multiTouchDrag;
|
|
12637
12677
|
this.trackpadGesture = trackpadGesture;
|
|
12678
|
+
this.zoomAround = zoomAround;
|
|
12638
12679
|
this.keyboard = keyboard;
|
|
12639
12680
|
const constraintChanged = !oldProps || oldProps.height !== props.height || oldProps.width !== props.width || oldProps.maxBounds !== props.maxBounds || oldProps.maxBoundsPadding !== props.maxBoundsPadding;
|
|
12640
12681
|
if (constraintChanged && props.maxBounds) {
|
|
@@ -12868,8 +12909,9 @@ void main(void) {
|
|
|
12868
12909
|
if (delta < 0 && scale5 !== 0) {
|
|
12869
12910
|
scale5 = 1 / scale5;
|
|
12870
12911
|
}
|
|
12871
|
-
const
|
|
12872
|
-
const
|
|
12912
|
+
const zoomPosition = this.getZoomPosition(pos);
|
|
12913
|
+
const transitionProps = smooth ? { ...this._getTransitionProps({ around: zoomPosition }), transitionDuration: 250 } : NO_TRANSITION_PROPS;
|
|
12914
|
+
const newControllerState = this.controllerState.zoom({ pos: zoomPosition, scale: scale5 });
|
|
12873
12915
|
this.updateViewport(newControllerState, transitionProps, {
|
|
12874
12916
|
isZooming: true,
|
|
12875
12917
|
isPanning: true
|
|
@@ -12955,7 +12997,7 @@ void main(void) {
|
|
|
12955
12997
|
if (!this.isPointInBounds(pos, event)) {
|
|
12956
12998
|
return false;
|
|
12957
12999
|
}
|
|
12958
|
-
const newControllerState = this.controllerState.zoomStart({ pos }, this._getConstraintContext("zoom", "start")).rotateStart({ pos }, this._getConstraintContext("rotate", "start"));
|
|
13000
|
+
const newControllerState = this.controllerState.zoomStart({ pos: this.getZoomPosition(pos) }, this._getConstraintContext("zoom", "start")).rotateStart({ pos }, this._getConstraintContext("rotate", "start"));
|
|
12959
13001
|
pinchEventWorkaround._startPinchRotation = event.rotation;
|
|
12960
13002
|
pinchEventWorkaround._lastPinchEvent = event;
|
|
12961
13003
|
this.updateViewport(newControllerState, NO_TRANSITION_PROPS, { isDragging: true });
|
|
@@ -12974,7 +13016,7 @@ void main(void) {
|
|
|
12974
13016
|
const { scale: scale5 } = event;
|
|
12975
13017
|
const pos = this.getCenter(event);
|
|
12976
13018
|
newControllerState = newControllerState.zoom(
|
|
12977
|
-
{ pos, scale: scale5 },
|
|
13019
|
+
{ pos: this.getZoomPosition(pos), scale: scale5 },
|
|
12978
13020
|
this._getConstraintContext("zoom", "update")
|
|
12979
13021
|
);
|
|
12980
13022
|
}
|
|
@@ -13002,15 +13044,16 @@ void main(void) {
|
|
|
13002
13044
|
const { _lastPinchEvent } = pinchEventWorkaround;
|
|
13003
13045
|
if (this.touchZoom && inertia && _lastPinchEvent && event.scale !== _lastPinchEvent.scale) {
|
|
13004
13046
|
const pos = this.getCenter(event);
|
|
13047
|
+
const zoomPosition = this.getZoomPosition(pos);
|
|
13005
13048
|
let newControllerState = this.controllerState.rotateEnd();
|
|
13006
13049
|
const z = Math.log2(event.scale);
|
|
13007
13050
|
const velocityZ = (z - Math.log2(_lastPinchEvent.scale)) / (event.deltaTime - _lastPinchEvent.deltaTime);
|
|
13008
13051
|
const endScale = Math.pow(2, z + velocityZ * inertia / 2);
|
|
13009
|
-
newControllerState = newControllerState.zoom({ pos, scale: endScale }).zoomEnd();
|
|
13052
|
+
newControllerState = newControllerState.zoom({ pos: zoomPosition, scale: endScale }).zoomEnd();
|
|
13010
13053
|
this.updateViewport(
|
|
13011
13054
|
newControllerState,
|
|
13012
13055
|
{
|
|
13013
|
-
...this._getTransitionProps({ around:
|
|
13056
|
+
...this._getTransitionProps({ around: zoomPosition }),
|
|
13014
13057
|
transitionDuration: inertia,
|
|
13015
13058
|
transitionEasing: INERTIA_EASING
|
|
13016
13059
|
},
|
|
@@ -13055,8 +13098,12 @@ void main(void) {
|
|
|
13055
13098
|
return false;
|
|
13056
13099
|
}
|
|
13057
13100
|
const isZoomOut = this.isFunctionKeyPressed(event);
|
|
13058
|
-
const
|
|
13059
|
-
|
|
13101
|
+
const zoomPosition = this.getZoomPosition(pos);
|
|
13102
|
+
const newControllerState = this.controllerState.zoom({
|
|
13103
|
+
pos: zoomPosition,
|
|
13104
|
+
scale: isZoomOut ? 0.5 : 2
|
|
13105
|
+
});
|
|
13106
|
+
this.updateViewport(newControllerState, this._getTransitionProps({ around: zoomPosition }), {
|
|
13060
13107
|
isZooming: true,
|
|
13061
13108
|
isPanning: true
|
|
13062
13109
|
});
|
|
@@ -13073,14 +13120,14 @@ void main(void) {
|
|
|
13073
13120
|
this._doubleClickDragAnchor = null;
|
|
13074
13121
|
return false;
|
|
13075
13122
|
}
|
|
13076
|
-
this._doubleClickDragAnchor = pos;
|
|
13123
|
+
this._doubleClickDragAnchor = this.getZoomPosition(pos);
|
|
13077
13124
|
let newControllerState = this.controllerState.zoomStart(
|
|
13078
|
-
{ pos },
|
|
13125
|
+
{ pos: this._doubleClickDragAnchor },
|
|
13079
13126
|
this._getConstraintContext("zoom", "start")
|
|
13080
13127
|
);
|
|
13081
13128
|
if (event.scale !== 1) {
|
|
13082
13129
|
newControllerState = newControllerState.zoom(
|
|
13083
|
-
{ pos, scale: event.scale },
|
|
13130
|
+
{ pos: this._doubleClickDragAnchor, scale: event.scale },
|
|
13084
13131
|
this._getConstraintContext("zoom", "update")
|
|
13085
13132
|
);
|
|
13086
13133
|
}
|