高性能网站建设 下载大连工业大学图书馆

当前位置: 首页 > news >正文

高性能网站建设 下载,大连工业大学图书馆,app制作收费价目表,企业网站建设制作多少钱上篇文章中#xff0c;我们介绍了使用viewer.entities.add添加entity之后的信号传递以及最后entity对象被传递到GeometryVisualizer#xff1b; 这篇文章#xff0c;我们则介绍如何在逐帧渲染的过程中根据GeometryVisualizer中的entity对象创建相应的primitive 这是下文中…上篇文章中我们介绍了使用viewer.entities.add添加entity之后的信号传递以及最后entity对象被传递到GeometryVisualizer 这篇文章我们则介绍如何在逐帧渲染的过程中根据GeometryVisualizer中的entity对象创建相应的primitive 这是下文中涉及到的类的类图从中可以清晰的了解各个对象之间的关系下面我们结合代码来仔细讲解。 循环的一帧 我们先看下viewer初始化的时候做了什么在何处定义了每一帧的循环并持续的进行渲染结合时序图见第三节和源码可以将其分为两个部分 Viewer初始化 viewer初始化并创建clock function Viewer(container, options){let clock;let clockViewModel;let destroyClockViewModel false;if (defined(options.clockViewModel)) {clockViewModel options.clockViewModel;clock clockViewModel.clock;} else {clock new Clock();clockViewModel new ClockViewModel(clock);destroyClockViewModel true;} }将clock作为参数之一创建cesiumWidget // 省略其他参数 const cesiumWidget new CesiumWidget(cesiumWidgetContainer, {clock: clock});添加监听事件建立事件响应其效果我们在后面再具体描述 eventHelper.add(clock.onTick, Viewer.prototype._onTick, this);cesiumWidget初始化 在构造函数中设置渲染循环策略this.useDefaultRenderLoop this._useDefaultRenderLoop undefined; this.useDefaultRenderLoop defaultValue(options.useDefaultRenderLoop,true );结合useDefaultRenderLoop的set函数可知其实是调用了startRenderLoop函数 useDefaultRenderLoop: {get: function () {return this._useDefaultRenderLoop;},set: function (value) {if (this._useDefaultRenderLoop ! value) {this._useDefaultRenderLoop value;if (value !this._renderLoopRunning) {startRenderLoop(this);}}}, }在startRenderLoop中定义了render函数并每一帧进行调用 function startRenderLoop(widget) {widget._renderLoopRunning true;let lastFrameTime 0;function render(frameTime) {// 此处省略细节widget.render();requestAnimationFrame(render);}requestAnimationFrame(render); }在render函数中起实际作用的是函数widget.render其内部通过调用this._clock.tick()发出信号结合上一节viewer初始化中提到的事件监听的建立可以知道进行响应的是Viewer.prototype._onTick函数 CesiumWidget.prototype.render function () {if (this._canRender) {this._scene.initializeFrame();const currentTime this._clock.tick();this._scene.render(currentTime);} else {this._clock.tick();} };Clock.prototype.tick function () {this.onTick.raiseEvent(this);return currentTime; };在Viewer.prototype._onTick函数中会通过调用函数this._dataSourceDisplay.update(time)进行实际的primitive对象的创建 Viewer.prototype._onTick function (clock) {const isUpdated this._dataSourceDisplay.update(time); };时序图 这里我们附上整个过程的时序图帮助大家更好的了解整个过程
生成Primitive 通过上面的描述我们知道了cesium的每一帧是如何更新的以及其通过调用this._dataSourceDisplay.update(time)进行primitive的创建下面我们就探究下具体的创建过程 在update中获取了this._defaultDataSource的_visualizers属性通过上一篇文章我们知道其是一个包含了GeometryVisualizer等多个Visualizer的列表其中GeometryVisualizer是后续创建polygon对应primitive的类 DataSourceDisplay.prototype.update function (time) {visualizers this._defaultDataSource._visualizers;vLength visualizers.length;for (x 0; x vLength; x) {result visualizers[x].update(time) result;}return result; };在GeometryVisualizer的update函数中主要做了如下几件事: 获取被添加对象在上一篇文章中我们知道通过_onCollectionChanged函数将添加的entity添加到了this._addedObjects属性中 const addedObjects this._addedObjects; addedObjects.set(id, entity);遍历每一个被添加的对象 创建UpdaterSet其内部的updaters包含了PolygonGeometryUpdater在内的10个Updater 通过updater尝试创建instance后面详细介绍 移除已经被添加的对象 在batch中创建primitive后面详细介绍
代码节选如下 GeometryVisualizer.prototype.update function (time) {// 获取被添加对象const addedObjects this._addedObjects;const added addedObjects.values;// 遍历每一个被添加的对象for (i added.length - 1; i -1; i–) {entity added[i];id entity.id;// 创建UpdaterSetupdaterSet new GeometryUpdaterSet(entity, this._scene);this._updaterSets.set(id, updaterSet);// 通过每一个updater尝试创建instance 并添加到batch中updaterSet.forEach(function (updater) {that._insertUpdaterIntoBatch(time, updater);});}// 移除已经被添加的对象addedObjects.removeAll();// 在batch中创建primitivelet isUpdated true;const batches this._batches;const length batches.length;for (i 0; i length; i) {isUpdated batches[i].update(time) isUpdated;}return isUpdated; };生成instance 获取polygonOutline对应的instance 在函数GeometryVisualizer.prototype._insertUpdaterIntoBatch中将updater传递到StaticOutlineGeometryBatch.prototype.add函数中 this._outlineBatches[shadows].add(time, updater);在StaticOutlineGeometryBatch.prototype.add先创建polygonOutline对应的instance const instance updater.createOutlineGeometryInstance(time);StaticOutlineGeometryBatch.prototype.add中调用batch.add函数传入instance并写入字典this.geometry this.geometry.set(id, instance);获取polygon对应的instance 同样在函数GeometryVisualizer.prototype._insertUpdaterIntoBatch中将updater传递到StaticGeometryColorBatch.prototype.add函数中 this._closedColorBatches[shadows].add(time, updater);在StaticGeometryColorBatch.prototype.add先创建polygon对应的instance const instance updater.createFillGeometryInstance(time);StaticGeometryColorBatch.prototype.add中调用batch.add函数传入instance并写入字典this.geometry this.geometry.set(id, instance);生成primitive 在循环中遍历所有的GeometryBatch对象并update 生成polygonOutline对应的primitive 通过StaticOutlineGeometryBatch.prototype.update遍历solidBatchesLength属性并update 在batch.update中生成primitive 生成polygon对应的primitive 通过StaticGeometryColorBatch.prototype.update调用updateItems函数在其内部遍历batch并update 在batch.update中生成primitive
时序图 在这里我们附上整个过程的时序图可以帮助大家更好的了解整个过程
后续 后面我们会进一步探索创建得到的primitive如何被渲染并对比其和我们直接添加的primitive在组织结构上有什么区别