Skip to content

Commit c2167d7

Browse files
authored
fix: fix 3dtiles picking on macos, close maptalks/issues#470 (#2635)
* fix: fix 3dtiles picking on macos, close maptalks/issues#470 * fix 3dtiles specs
1 parent 25a47bf commit c2167d7

File tree

8 files changed

+115
-6
lines changed

8 files changed

+115
-6
lines changed

packages/gl/src/reshader/common/REGLHelper.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ export function getMaterialType(type) {
1818
}
1919

2020

21+
export function getArrayType(array) {
22+
if (array instanceof Uint8Array) {
23+
return 'uint8';
24+
} else if (array instanceof Int8Array) {
25+
return 'int8';
26+
} else if (array instanceof Uint16Array) {
27+
return 'uint16';
28+
} else if (array instanceof Int16Array) {
29+
return 'int16';
30+
} else {
31+
return 'float';
32+
}
33+
}
34+
2135
const materialFormats = {
2236
0x1906: 'alpha',
2337
0x1907: 'rgb',
@@ -100,6 +114,9 @@ export function getUniqueREGLBuffer(regl, data, options) {
100114
extend(info, options);
101115
}
102116
info.data = array;
117+
if (!info.type) {
118+
info.type = getArrayType(array);
119+
}
103120
buffer = regl.buffer(info);
104121
// console.log(count++, (array.byteLength / 1024 / 1024).toFixed(1));
105122
arrayBuffer[BUFFER_KEY][byteOffset] = buffer;

packages/gl/src/reshader/common/Util.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ export function clamp(n: number, min: number, max: number) {
241241
* @returns
242242
*/
243243
export function isSupportVAO(regl: any) {
244+
if (globalThis['MAPTALKS_DISABLE_VAO']) {
245+
return false;
246+
}
244247
if (regl.wgpu) {
245248
return false;
246249
}

packages/gl/src/reshader/pbr/glsl/depth.vert

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#define SHADER_NAME depth_vert
2-
precision highp float;
32

43
attribute vec3 aPosition;
54
#include <line_extrusion_vert>

packages/gl/src/reshader/pbr/glsl/standard.vert

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include <gl2_vert>
22
#define SHADER_NAME PBR
3-
precision highp float;
43

54
attribute vec3 aPosition;
65

packages/gl/src/reshader/water/water.vert

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
precision highp float;
2-
precision highp sampler2D;
31
const float PI = 3.141592653589793;
42
uniform mat4 projMatrix;
53
uniform mat4 viewMatrix;

packages/layer-3dtiles/src/layer/renderer/TileMeshPainter.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as maptalks from 'maptalks';
22
import { reshader, vec3, vec4, mat3, mat4, quat, HighlightUtil, ContextUtil } from '@maptalks/gl';
33
import { iterateMesh, iterateBufferData, getItemAtBufferData, setInstanceData, } from '../../common/GLTFHelpers';
4+
import pickingVert from './glsl/picking.vert';
45
import pntsVert from './glsl/pnts.vert';
56
import pntsFrag from './glsl/pnts.frag';
67
import { isFunction, isNil, extend, setColumn3, flatArr, isNumber, normalizeColor, pushIn } from '../../common/Util';
@@ -10,7 +11,9 @@ import { isFunctionDefinition, interpolated } from '@maptalks/function-type';
1011
// import { getKHR_techniques } from './s3m/S3MTechnique';
1112

1213

13-
const { getTextureMagFilter, getTextureMinFilter, getTextureWrap, getMaterialType, getMaterialFormat, getPrimitive, getUniqueREGLBuffer } = reshader.REGLHelper;
14+
const { getTextureMagFilter, getTextureMinFilter,
15+
getTextureWrap, getMaterialType, getMaterialFormat,
16+
getPrimitive, getUniqueREGLBuffer, getArrayType } = reshader.REGLHelper;
1417

1518
const Y_TO_Z = [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1];
1619
const X_TO_Z = [0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1];
@@ -1452,6 +1455,7 @@ export default class TileMeshPainter {
14521455
const isWebGPU = this.getMap().getRenderer().isWebGPU();
14531456
const attrs = {};
14541457
let positionSize = 0;
1458+
let vertexCount = 0;
14551459
for (const p in attributes) {
14561460
// 优先采用 attributeSemantics中定义的属性
14571461
const name = attributeSemantics[p] || p;
@@ -1478,11 +1482,19 @@ export default class TileMeshPainter {
14781482

14791483
attrs[name] = extend({}, attributes[p]);
14801484
attrs[name].buffer = buffer;
1485+
attrs[name].type = getArrayType(attrs[name].array);
14811486
delete attrs[name].array;
14821487
if (name === attributeSemantics['POSITION']) {
14831488
attrs[name].array = attributes[p].array;
1489+
vertexCount = attributes[p].array.length / 3;
14841490
}
14851491
}
1492+
// 补上缺失的_BATHCID属性,解决macos下 vertex buffer not big enough 报错
1493+
const pickingIdAttribute = attributeSemantics['_BATCHID'];
1494+
if (!attrs[pickingIdAttribute] && !isI3DM) {
1495+
const pickingData = new Uint8Array(vertexCount);
1496+
attrs[pickingIdAttribute] = pickingData;
1497+
}
14861498
// createColorArray(attrs);
14871499
const indices = gltfMesh.indices ? (gltfMesh.indices.array ? gltfMesh.indices.array.slice() : gltfMesh.indices) : null;
14881500
const geometry = new reshader.Geometry(
@@ -1679,7 +1691,7 @@ export default class TileMeshPainter {
16791691
this.picking = new reshader.FBORayPicking(
16801692
this._renderer,
16811693
{
1682-
vert: this._standardShader.vert,
1694+
vert: pickingVert,
16831695
extraCommandProps,
16841696
uniforms: this._standardShader.uniforms,
16851697
defines: {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <gl2_vert>
2+
#define SHADER_NAME GEO_3DTILES_PICKING
3+
4+
attribute vec3 aPosition;
5+
6+
#if defined(HAS_COLOR)
7+
attribute vec4 aColor;
8+
#endif
9+
#if defined(HAS_COLOR0)
10+
#if COLOR0_SIZE == 3
11+
attribute vec3 aColor0;
12+
varying vec3 vColor0;
13+
#else
14+
attribute vec4 aColor0;
15+
varying vec4 vColor0;
16+
#endif
17+
#endif
18+
19+
20+
uniform mat4 modelMatrix;
21+
uniform mat4 modelViewMatrix;
22+
uniform mat4 positionMatrix;
23+
uniform mat4 projMatrix;
24+
25+
#include <line_extrusion_vert>
26+
#include <get_output>
27+
28+
#include <fbo_picking_vert>
29+
void main() {
30+
mat4 localPositionMatrix = getPositionMatrix();
31+
vec4 localVertex = getPosition(aPosition);
32+
33+
vec4 position = localPositionMatrix * localVertex;
34+
vec4 viewVertex = modelViewMatrix * position;
35+
36+
#ifdef HAS_MASK_EXTENT
37+
gl_Position = projMatrix * getMaskPosition(position, modelMatrix);
38+
#else
39+
gl_Position = projMatrix * viewVertex;
40+
#endif
41+
42+
float alpha = 1.0;
43+
#if defined(HAS_COLOR)
44+
alpha *= aColor.a;
45+
#endif
46+
#if defined(HAS_COLOR0) && COLOR0_SIZE == 4
47+
alpha *= aColor0.a;
48+
#endif
49+
50+
fbo_picking_setData(gl_Position.w, alpha != 0.0);
51+
52+
53+
}

packages/layer-3dtiles/test/layer.identify.spec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const maptalks = require('maptalks');
22
require('@maptalks/gl');
3+
const { GroupGLLayer } = require('@maptalks/gl');
34
require('@maptalks/transcoders.draco');
45
require('@maptalks/transcoders.ktx2');
56
require('@maptalks/transcoders.crn');
@@ -42,6 +43,33 @@ describe('3dtiles identify specs', () => {
4243
document.body.innerHTML = '';
4344
});
4445

46+
it('can identify b3dm data in MacOS, maptalks/issues#470', done => {
47+
globalThis['MAPTALKS_DISABLE_VAO'] = true;
48+
const resPath = 'BatchedDraco/dayanta/';
49+
const layer = new Geo3DTilesLayer('3d-tiles', {
50+
services : [
51+
{
52+
url : `http://localhost:${PORT}/integration/fixtures/${resPath}/tileset.json`,
53+
shader: 'phong',
54+
heightOffset: -420
55+
}
56+
]
57+
});
58+
const group = new GroupGLLayer('group', [layer]);
59+
group.addTo(map);
60+
layer.once('loadtileset', () => {
61+
const extent = layer.getExtent(0);
62+
map.fitExtent(extent, 0, { animation: false });
63+
setTimeout(function() {
64+
const point = new maptalks.Point(255, 497);
65+
const hits = layer.identifyAtPoint(point);
66+
assert(hits[0].data.batchId === 0);
67+
globalThis['MAPTALKS_DISABLE_VAO'] = false;
68+
done();
69+
}, 1500);
70+
});
71+
}).timeout(5000);
72+
4573
it('can identify b3dm data', done => {
4674
const resPath = 'Cesium3DTiles/Batched/BatchedWithBatchTable';
4775
const layer = new Geo3DTilesLayer('3d-tiles', {

0 commit comments

Comments
 (0)