Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geo3DTilesLayer i3s service adapt texture dds format #27

Merged
merged 3 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/layer-3dtiles/src/layer/Geo3DTilesLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ export default class Geo3DTilesLayer extends MaskLayerMixin(maptalks.Layer) {
if (!root || !root.visible) {
continue;
}
const service = root.service;
// let firstContentLevel = Infinity;
const queue: TileNode[] = [root];
const maxExtent = this._getRootMaxExtent(i);
Expand All @@ -408,6 +409,8 @@ export default class Geo3DTilesLayer extends MaskLayerMixin(maptalks.Layer) {
// debugger
// }
const visible = this._isVisible(node, maxExtent, projectionView, mapExtentBBOX, clipMasks);
//record service
node.service = service;


// // find ancestors
Expand Down Expand Up @@ -1877,7 +1880,8 @@ export type TileNode = {
//@internal
_tileRegion?: TileBoundingRegion,
hasParentContent?: boolean,
extent?: maptalks.Extent
extent?: maptalks.Extent,
service?: Record<string, any>
};

export type RootTileNode = {
Expand Down
63 changes: 44 additions & 19 deletions packages/layer-3dtiles/src/layer/i3s/I3SHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const supportWASM = (() => {
if (module instanceof WebAssembly.Module)
return new WebAssembly.Instance(module) instanceof WebAssembly.Instance;
}
/* eslint-disable no-empty */
/* eslint-disable no-empty */
} catch (e) {
}
/* eslint-enable no-empty */
Expand Down Expand Up @@ -86,7 +86,7 @@ export function getI3SNodeInfo(url, nodeCache, regl, enableDraco, forceDraco) {
if (isESLPK) {
geoUrl += '.bin';
}
const meshInfo = { geometry: { url: geoUrl, info: nodeCache.layerScene.store.defaultGeometrySchema }};
const meshInfo = { geometry: { url: geoUrl, info: nodeCache.layerScene.store.defaultGeometrySchema } };
let textureUrl = node.textureData && node.textureData[0] && node.textureData[0].href;
if (textureUrl) {
const mimeType = nodeCache.layerScene.store.textureEncoding[0];
Expand All @@ -101,7 +101,7 @@ export function getI3SNodeInfo(url, nodeCache, regl, enableDraco, forceDraco) {
}
const matInfo = {
pbrMetallicRoughness: {
baseColorTexture:{
baseColorTexture: {
url: baseUrl + `/nodes/${node.id}/` + textureUrl,
factor: 1,
format,
Expand All @@ -118,6 +118,8 @@ export function getI3SNodeInfo(url, nodeCache, regl, enableDraco, forceDraco) {
geometry = node.mesh.geometry;
material = node.mesh.material;
const geoDefinitions = nodeCache.layerScene.geometryDefinitions;
//read texture encode array
const textureEncoding = (nodeCache.layerScene.store || {}).textureEncoding;
const geoDef = geoDefinitions[geometry.definition];
const { geometryBuffers } = geoDef;
// geometryBuffers[1] is the draco version
Expand All @@ -128,7 +130,7 @@ export function getI3SNodeInfo(url, nodeCache, regl, enableDraco, forceDraco) {
if (isESLPK) {
geoUrl += '.bin';
}
const meshInfo = { geometry: { url: geoUrl, info: geometryInfo }};
const meshInfo = { geometry: { url: geoUrl, info: geometryInfo } };
if (forceDraco && supportWASM && hasCompression && !transcoders['draco']) {
throw new Error('Must import @maptalks/transcoder.draco to load i3s draco compressed geometry');
}
Expand All @@ -142,7 +144,7 @@ export function getI3SNodeInfo(url, nodeCache, regl, enableDraco, forceDraco) {
let materialInfo;
if (materialDefinitions) {
const resource = material.resource;
materialInfo = parseMaterial(materialDef, textureSetDefinitions, baseUrl, resource, regl, nodeCache.layerScene.eslpk);
materialInfo = parseMaterial(textureEncoding, materialDef, textureSetDefinitions, baseUrl, resource, regl, nodeCache.layerScene.eslpk);
} else {
materialInfo = {
pbrMetallicRoughness: {
Expand All @@ -165,20 +167,20 @@ export function getI3SNodeInfo(url, nodeCache, regl, enableDraco, forceDraco) {
};
}

function parseMaterial(materialDefinition, textureSetDefinitions, baseUrl, nodeIndex, regl, isESLPK) {
function parseMaterial(textureEncoding, materialDefinition, textureSetDefinitions, baseUrl, nodeIndex, regl, isESLPK) {
const matInfo = JSON.parse(JSON.stringify(materialDefinition));

resolveTextures(matInfo, textureSetDefinitions, baseUrl, nodeIndex, regl, isESLPK);
resolveTextures(textureEncoding, matInfo, textureSetDefinitions, baseUrl, nodeIndex, regl, isESLPK);
return matInfo;
}

function resolveTextures(matInfo, textureSetDefinitions, baseUrl, resource, regl, isESLPK) {
function resolveTextures(textureEncoding, matInfo, textureSetDefinitions, baseUrl, resource, regl, isESLPK) {
for (const p in matInfo) {
// is a texture
if (matInfo[p] && matInfo[p].textureSetDefinitionId >= 0) {
const texDef = textureSetDefinitions[matInfo[p].textureSetDefinitionId];
const mimeType = 'images/' + texDef.formats[0].format;
const format = getSupportedTexture(texDef.formats, regl);
const format = getSupportedTexture(texDef.formats, regl, textureEncoding);
const texture = {
url: baseUrl + `/nodes/${resource}/textures/${format.name}`,
factor: matInfo[p].factor === undefined ? 1 : matInfo[p].factor,
Expand All @@ -187,25 +189,48 @@ function resolveTextures(matInfo, textureSetDefinitions, baseUrl, resource, regl
};
if (isESLPK) {
let ext = '';
switch(format.format) {
case 'dds':
ext = 'bin.dds';
break;
case 'jpg':
case 'png':
ext = format.format;
break;
switch (format.format) {
case 'dds':
ext = 'bin.dds';
break;
case 'jpg':
case 'png':
ext = format.format;
break;
}
texture.url += '.' + ext;
}
matInfo[p] = texture;
} else if (isObject(matInfo[p])) {
resolveTextures(matInfo[p], textureSetDefinitions, baseUrl, resource, regl, isESLPK);
resolveTextures(textureEncoding, matInfo[p], textureSetDefinitions, baseUrl, resource, regl, isESLPK);
}
}
}

function getSupportedTexture(formats, regl) {
const textureEnCodingMap = {
"image/jpeg": 'jpg',
"image/jpg": 'jpg',
"image/png": 'jpg',
"image/vnd-ms.dds": "dds",
"image/ktx": 'jpg'
};

function getSupportedTexture(formats, regl, textureEncoding) {
if (textureEncoding && textureEncoding.length) {
const textureEncode = textureEncoding[textureEncoding.length - 1];
const textureFormat = textureEnCodingMap[textureEncode];
if (!textureFormat) {
console.error(`i3s not find texture format type from:`, textureEnCodingMap, 'current textureEncoding:', textureEncode);
} else {
for (let i = 0, len = formats.length; i < len; i++) {
const format = formats[i].format;
if (format === textureFormat) {
return formats[i];
}
}
}

}
// for (let i = formats.length - 1; i >= 0; i--) {
for (let i = 0; i <= formats.length; i++) {
const format = formats[i].format;
Expand Down
38 changes: 21 additions & 17 deletions packages/layer-3dtiles/src/layer/renderer/Geo3DTilesRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
this.painter.prepareRender(parentContext);
this._consumeI3SQueue();
this._consumeModelQueue(parentContext);
const { selectedTiles, leaves, requests} = this._selectTiles(root, tiles);
const { selectedTiles, leaves, requests } = this._selectTiles(root, tiles);

if (requests.length) {
this.loadTiles(requests);
Expand Down Expand Up @@ -344,15 +344,15 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
this.tileCache.shrink();
}

onDrawTileStart() {}
onDrawTileEnd() {}
onDrawTileStart() { }
onDrawTileEnd() { }

loadTiles(queue) {
for (let i = 0, l = queue.length; i < l; i++) {
const node = queue[i];
// tile image's loading may not be async
this.tilesLoading[node.id] = {
current : true,
current: true,
node
};
this.loadTile(node);
Expand Down Expand Up @@ -396,7 +396,7 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
url = encodeSuperMapURI(url, tile.baseUrl);
}
const requestUrl = this.layer.getTileUrl(url, this.layer._roots[tile._rootIdx]);
const params = { url: requestUrl, arraybuffer, rootIdx : tile._rootIdx, upAxis : tile._upAxis, transform: tile.matrix, supportedFormats };
const params = { url: requestUrl, arraybuffer, rootIdx: tile._rootIdx, upAxis: tile._upAxis, transform: tile.matrix, supportedFormats };

if (isI3SMesh(url)) {
const nodeCache = this._i3sNodeCache[tile._rootIdx];
Expand Down Expand Up @@ -614,8 +614,8 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
_addErrorToCache(node, err) {
const tileData = {
// image : data,
loadTime : maptalks.Util.now(),
current : true,
loadTime: maptalks.Util.now(),
current: true,
error: err,
node
};
Expand All @@ -626,8 +626,8 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
_addTileToCache(node) {
const tileData = {
// image : data,
loadTime : maptalks.Util.now(),
current : true,
loadTime: maptalks.Util.now(),
current: true,
node
};
tileData.renderer = this;
Expand Down Expand Up @@ -658,8 +658,8 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
const attributes = layer.options.glOptions || {
alpha: true,
depth: true,
stencil : true,
preserveDrawingBuffer : true,
stencil: true,
preserveDrawingBuffer: true,
antialias: layer.options.antialias,
};
const inGroup = this.canvas.gl && this.canvas.gl.wrap;
Expand All @@ -671,12 +671,12 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
this.gl = this._createGLContext(this.canvas, attributes);
}
this.regl = this.regl || createREGL({
gl : this.gl,
gl: this.gl,
attributes,
extensions : [
extensions: [
'OES_element_index_uint'
],
optionalExtensions : layer.options['optionalExtensions'] || []
optionalExtensions: layer.options['optionalExtensions'] || []
});
this.prepareWorker();
if (inGroup) {
Expand Down Expand Up @@ -751,7 +751,7 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
this.regl.clear({
color: [0, 0, 0, 0],
depth: 1,
stencil : 0
stencil: 0
});
}

Expand Down Expand Up @@ -812,7 +812,7 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
for (let i = 0; i < names.length; ++i) {
try {
context = canvas.getContext(names[i], options);
} catch (e) {}
} catch (e) { }
if (context) {
break;
}
Expand Down Expand Up @@ -860,7 +860,7 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
promises.push(Ajax.getJSON(url, fetchOptions).then(json => {
delete this._i3sRequests[url];
const nodeCache = this._i3sNodeCache[rootIdx];
if (!nodeCache) {
if (!nodeCache) {
this.setToRedraw();
return;
}
Expand Down Expand Up @@ -919,6 +919,10 @@ export default class Geo3DTilesRenderer extends MaskRendererMixin(maptalks.rende
if (tileset.spatialReference && (!tileset.spatialReference.wkid || tileset.spatialReference.wkid !== 4326)) {
console.warn('i3s has a spatialReference other than 4326.', tileset.spatialReference);
}
if (tileset.spatialReference && tileset.spatialReference.wkid === 4490) {
console.warn('i3s spatialReference is 4490,auto set spatialReference to 4326,This may cause some location issues, please ensure that your service is 4326');
tileset.spatialReference.wkid = 4326;
}
nodeCache.projection = tileset.spatialReference;
parseI3SJSON(this.layer, tileset, rootIdx, service, url, nodeCache, this._fnFetchNodepages).then(json => {
this.onTilesetLoad(json, parent, url);
Expand Down