primitive动态修改

发布时间 2023-12-29 11:45:09作者: 邢韬

以贴底线 GroundPolylinePrimitive 为例

我们知道,primitive的更新机制主要是通过update函数,所以通过源码我们可以很容易找到如何对针对性的更新属性。

可以看到,update 每次都会判断 _primitive 这个属性,如果他未定义,则重新构建geometry相关的属性,所以我们只需要将_primitive清空,然后让他自己重构即可。

注:记的设置 asynchronous 为 false,默认异步抖动严重。

primitive._primitive = undefined;
primitive.geometryInstances = [geometryInstances];

源码中update如下:

GroundPolylinePrimitive.prototype.update = function (frameState) {
  ...省略
var that = this; var primitiveOptions = this._primitiveOptions; if (!defined(this._primitive)) { var geometryInstances = Array.isArray(this.geometryInstances) ? this.geometryInstances : [this.geometryInstances]; var geometryInstancesLength = geometryInstances.length; var groundInstances = new Array(geometryInstancesLength); var attributes; // Check if each instance has a color attribute. for (i = 0; i < geometryInstancesLength; ++i) { attributes = geometryInstances[i].attributes; if (!defined(attributes) || !defined(attributes.color)) { this._hasPerInstanceColors = false; break; } } for (i = 0; i < geometryInstancesLength; ++i) { var geometryInstance = geometryInstances[i]; attributes = {}; var instanceAttributes = geometryInstance.attributes; for (var attributeKey in instanceAttributes) { if (instanceAttributes.hasOwnProperty(attributeKey)) { attributes[attributeKey] = instanceAttributes[attributeKey]; } } // Automatically create line width attribute if not already given if (!defined(attributes.width)) { attributes.width = new GeometryInstanceAttribute({ componentDatatype: ComponentDatatype.UNSIGNED_BYTE, componentsPerAttribute: 1.0, value: [geometryInstance.geometry.width], }); } // Update each geometry for framestate.scene3DOnly = true and projection geometryInstance.geometry._scene3DOnly = frameState.scene3DOnly; GroundPolylineGeometry.setProjectionAndEllipsoid( geometryInstance.geometry, frameState.mapProjection ); groundInstances[i] = new GeometryInstance({ geometry: geometryInstance.geometry, attributes: attributes, id: geometryInstance.id, pickPrimitive: that, }); } primitiveOptions.geometryInstances = groundInstances; primitiveOptions.appearance = this.appearance; primitiveOptions._createShaderProgramFunction = function ( primitive, frameState, appearance ) { createShaderProgram(that, frameState, appearance); }; primitiveOptions._createCommandsFunction = function ( primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands ) { createCommands( that, appearance, material, translucent, colorCommands, pickCommands ); }; primitiveOptions._updateAndQueueCommandsFunction = function ( primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses ) { updateAndQueueCommands( that, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume ); }; this._primitive = new Primitive(primitiveOptions); this._primitive.readyPromise.then(function (primitive) { that._ready = true; if (that.releaseGeometryInstances) { that.geometryInstances = undefined; } var error = primitive._error; if (!defined(error)) { that._readyPromise.resolve(that); } else { that._readyPromise.reject(error); } }); } if ( this.appearance instanceof PolylineColorAppearance && !this._hasPerInstanceColors ) { throw new DeveloperError( "All GeometryInstances must have color attributes to use PolylineColorAppearance with GroundPolylinePrimitive." ); } this._primitive.appearance = this.appearance; this._primitive.show = this.show; this._primitive.debugShowBoundingVolume = this.debugShowBoundingVolume; this._primitive.update(frameState); };