From 383ba2df7e7201777385a2da36894736bfdbb982 Mon Sep 17 00:00:00 2001 From: shihui Date: Thu, 1 Dec 2022 23:17:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8F=90=E5=8F=96=E7=BD=91=E6=A0=BC?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E5=86=85=E5=AE=B9=E3=80=81=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../services/layer/StyleAttributeService.ts | 4 + packages/layers/src/point/index.ts | 2 +- packages/layers/src/point/models/fill.ts | 140 ++++++++++++++++-- 3 files changed, 133 insertions(+), 13 deletions(-) diff --git a/packages/core/src/services/layer/StyleAttributeService.ts b/packages/core/src/services/layer/StyleAttributeService.ts index be8f5f723d..2bca2caee3 100644 --- a/packages/core/src/services/layer/StyleAttributeService.ts +++ b/packages/core/src/services/layer/StyleAttributeService.ts @@ -283,6 +283,9 @@ export default class StyleAttributeService implements IStyleAttributeService { sizePerElement: 0, elements: [], }; + + + if (triangulation) { this.triangulation = triangulation; } @@ -423,6 +426,7 @@ export default class StyleAttributeService implements IStyleAttributeService { if (triangulation) { this.triangulation = triangulation; } + const descriptors = this.attributes.map((attr) => { attr.resetDescriptor(); return attr.descriptor; diff --git a/packages/layers/src/point/index.ts b/packages/layers/src/point/index.ts index f77334f9b3..759ce5c3bb 100644 --- a/packages/layers/src/point/index.ts +++ b/packages/layers/src/point/index.ts @@ -7,6 +7,6 @@ export default class PointLayer extends BaseLayer { public async buildModels() { const model = new FillModel(this); - this.models = model.initModels(); + this.models = model.buildModels(); } } diff --git a/packages/layers/src/point/models/fill.ts b/packages/layers/src/point/models/fill.ts index 9efc93c0d1..0e84a50b4a 100644 --- a/packages/layers/src/point/models/fill.ts +++ b/packages/layers/src/point/models/fill.ts @@ -2,7 +2,6 @@ import { AttributeType, gl, IEncodeFeature, - IModelUniform, ILayer, TYPES, IShaderModuleService, @@ -13,10 +12,11 @@ import { import pointFillFrag from '../shaders/fill_frag.glsl'; import pointFillVert from '../shaders/fill_vert.glsl'; - +import StyleAttribute from '../../../../core/src/services/layer/StyleAttribute' export default class FillModel { protected layer: ILayer; + private attributes: any[] = []; protected shaderModuleService: IShaderModuleService; @@ -43,15 +43,124 @@ export default class FillModel { this.registerBuiltinAttributes(); } - public getUninforms(): IModelUniform { - return { + public createAttributesAndIndices( + features: IEncodeFeature[], + triangulation: Triangulation, + segmentNumber: number, + ) { + + const descriptors = this.attributes.map((attr) => { + attr.resetDescriptor(); + return attr.descriptor; + }); + let verticesNum = 0; + let vecticesCount = 0; // 在不使用 element 的时候记录顶点、图层所有顶点的总数 + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const vertices: number[] = []; + const indices: number[] = []; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const normals: number[] = []; + let size = 3; + features.forEach((feature, featureIdx) => { + // 逐 feature 进行三角化 + const { + indices: indicesForCurrentFeature, + vertices: verticesForCurrentFeature, + normals: normalsForCurrentFeature, + size: vertexSize, + indexes, + count, + } = triangulation(feature, segmentNumber); + + if (typeof count === 'number') { + vecticesCount += count; + } + + indicesForCurrentFeature.forEach((i) => { + indices.push(i + verticesNum); + }); + size = vertexSize; + const verticesNumForCurrentFeature = + verticesForCurrentFeature.length / vertexSize; + + + verticesNum += verticesNumForCurrentFeature; + // 根据 position 顶点生成其他顶点数据 + for ( + let vertexIdx = 0; + vertexIdx < verticesNumForCurrentFeature; + vertexIdx++ + ) { + const normal = + normalsForCurrentFeature?.slice(vertexIdx * 3, vertexIdx * 3 + 3) || + []; + const vertice = verticesForCurrentFeature.slice( + vertexIdx * vertexSize, + vertexIdx * vertexSize + vertexSize, + ); + + let vertexIndex = 0; + if (indexes && indexes[vertexIdx] !== undefined) { + vertexIndex = indexes[vertexIdx]; + } + + descriptors.forEach((descriptor, attributeIdx) => { + if (descriptor && descriptor.update) { + (descriptor.buffer.data as number[]).push( + ...descriptor.update( + feature, + featureIdx, + vertice, + vertexIdx, // 当前顶点所在feature索引 + normal, + vertexIndex, + // 传入顶点索引 vertexIdx + ), + ); + } // end if + }); // end for each + } // end for + }); // end features for Each + const { + createAttribute, + createBuffer, + createElements, + } = this.rendererService; + + const attributes = {}; + + descriptors.forEach((descriptor, attributeIdx) => { + if (descriptor) { + // IAttribute 参数透传 + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { buffer, update, name, ...rest } = descriptor; + + const vertexAttribute = createAttribute({ + // IBuffer 参数透传 + buffer: createBuffer(buffer), + ...rest, + }); + attributes[descriptor.name || ''] = vertexAttribute; + + + } + }); + + const elements = createElements({ + data: indices, + type: gl.UNSIGNED_INT, + count: indices.length, + }); + const attributesAndIndices = { + attributes, + elements, + count: vecticesCount, }; + return attributesAndIndices; } - public initModels() { - return this.buildModels(); - } + public buildLayerModel( options: any ) { const { @@ -69,8 +178,7 @@ export default class FillModel { }); const { vs, fs, uniforms } = this.shaderModuleService.getModule(moduleName); const { createModel } = this.rendererService; - const { attributes, elements } = - this.styleAttributeService.createAttributesAndIndices( + const { attributes, elements } =this.createAttributesAndIndices( [{ color: [1, 0, 0, 1], coordinates: [120, 30], @@ -81,6 +189,7 @@ export default class FillModel { triangulation, segmentNumber, ); + const modelOptions = { attributes, uniforms, @@ -90,7 +199,7 @@ export default class FillModel { ...rest, }; - return createModel(modelOptions); + return createModel(modelOptions); } @@ -115,9 +224,16 @@ export default class FillModel { return [model]; } + public registerStyleAttribute( + options: any + ) { + const attributeToUpdate = new StyleAttribute(options); + this.attributes.push(attributeToUpdate); + } + protected registerBuiltinAttributes() { - this.styleAttributeService.registerStyleAttribute({ + this.registerStyleAttribute({ name: 'position', type: AttributeType.Attribute, descriptor: { @@ -139,7 +255,7 @@ export default class FillModel { }, }); - this.styleAttributeService.registerStyleAttribute({ + this.registerStyleAttribute({ name: 'extrude', type: AttributeType.Attribute, descriptor: {