cesium entity render

cesium 对 entity 的渲染过程大致分为两个分过程:

一、初始化

二、渲染

下面分此两个过程阐述:

一、初始化

1、在Viewer构造函数中初始化_dataSourceDisplay,

new Cesium.Viewer(container, options){

  ...

  dataSourceCollection = new DataSourceCollection();

  dataSourceDisplay = new DataSourceDisplay({

            scene : scene,
            dataSourceCollection : dataSourceCollection
        });
  this._dataSourceDisplay=dataSourceDisplay ;

}

并定义Entities属性

entities : {
  get : function() {
    return this._dataSourceDisplay.defaultDataSource.entities;
  }
},

2、在DataSourceDisplay构造函数中初始化一个CustomDataSource作为defaultDataSource

new Cesium.DataSourceDisplay(){

  var defaultDataSource = new CustomDataSource();

        this._onDataSourceAdded(undefined, defaultDataSource);

}

并在其中初始化_entityCollection

new Cesium.CustomDataSource(){

  this._entityCollection = new EntityCollection(this);

}

在_onDataSourceAdded中初始化_visualizers

DataSourceDisplay.prototype._onDataSourceAdded = function(dataSourceCollection, dataSource){
  dataSource._visualizers = this._visualizersCallback(scene, entityCluster, dataSource);
}
并初始化GeometryVisualizer
DataSourceDisplay.defaultVisualizersCallback = function(scene, entityCluster, dataSource) {
   var entities = dataSource.entities;
          return [new BillboardVisualizer(entityCluster, entities),
                   new GeometryVisualizer(scene, entities, dataSource._primitives, dataSource._groundPrimitives),
         ...
        ];
}
3、在GeometryVisualizer中对entities进行分组可视化
function GeometryVisualizer(scene, entityCollection, primitives, groundPrimitives) {
  this._outlineBatches = new Array(numberOfShadowModes*2);
        this._closedColorBatches = new Array(numberOfShadowModes*2);
        this._closedMaterialBatches = new Array(numberOfShadowModes*2);
        this._openColorBatches = new Array(numberOfShadowModes*2);
        this._openMaterialBatches = new Array(numberOfShadowModes*2);
   ...
  for (i = 0; i < numberOfShadowModes; ++i) {
    this._closedColorBatches[i] = new StaticGeometryColorBatch(primitives, PerInstanceColorAppearance,                            undefined, true, i, true);
    ....
  } 
  ...
  //是否贴地
  if (supportsMaterialsforEntitiesOnTerrain) {
            for (i = 0; i < numberOfClassificationTypes; ++i) {
                  groundMaterialBatches.push(new StaticGroundGeometryPerMaterialBatch(groundPrimitives, i,                                                 MaterialAppearance));
                  groundColorBatches[i] = new StaticGroundGeometryPerMaterialBatch(groundPrimitives, i,                                                       PerInstanceColorAppearance);
              }
          } else {
              for (i = 0; i < numberOfClassificationTypes; ++i) {
                  groundColorBatches[i] = new StaticGroundGeometryColorBatch(groundPrimitives, i);
              }
          }
    //事件绑定
    entityCollection.collectionChanged.addEventListener(GeometryVisualizer.prototype._onCollectionChanged,                            this);
    this._onCollectionChanged(entityCollection, entityCollection.values, emptyArray);
}
事件处理程序
GeometryVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed) {
  var addedObjects = this._addedObjects;
        var removedObjects = this._removedObjects;
        var changedObjects = this._changedObjects;
  for (i = added.length - 1; i > -1; i--) {
            entity = added[i];
            id = entity.id;
            if (removedObjects.remove(id)) {
                changedObjects.set(id, entity);
            } else {
                addedObjects.set(id, entity);
            }
        }
}
4、关于事件绑定
在以上三步的默认构造函数中,通过在viewer的dataSourceDisplay的defaultDataSource(customDataSource)中初始化一个entityCollecton,并在viewer中定义该属性,构造一个空的entityCollection。
而数据的传递则使用事件机制:
在EntityCollection里定义一个collectionChanged事件,
function EntityCollection(owner) {
  this._collectionChanged = new Event();
}
并在add函数里触发该事件
EntityCollection.prototype.add = function(entity) {
 fireChangedEvent(this);
}
function fireChangedEvent(collection) {
  collection._collectionChanged.raiseEvent(collection, addedArray, removedArray, changedArray);
}
而在第三步的geometryVisualizer里挂接该事件的处理程序,将添加的entity传递到geometryVisualizer的addedObjects数组。这样,无论在何时何地调用viewer.entities.add(entity),都会通过该事件绑定传入geometryVisualizer,从而为entity的渲染准备好数据。
posted @ 2022-05-24 15:18  jwwry  阅读(339)  评论(0编辑  收藏  举报