07-Cesium中的自定义MaterialProperty是如何返回material的完整代码解析

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://cesium.com/downloads/cesiumjs/releases/1.97/Build/Cesium/Cesium.js"></script>
    <link href="https://cesium.com/downloads/cesiumjs/releases/1.97/Build/Cesium/Widgets/widgets.css" rel="stylesheet" />

    <style>
      #map {
        width: 100vw;
        height: 100vh;
      }
    </style>
  </head>

  <body>
    <div id="map"></div>
    <script>
      Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhZjZkZDAwZC1mNTFhLTRhOTEtOGExNi00MzRhNGIzMDdlNDQiLCJpZCI6MTA1MTUzLCJpYXQiOjE2NjA4MDg0Njd9.qajeJtc4-kppqfR1--Y2FqCu5r3TE1xYYGnEQhy-JF0'
      const viewer = new Cesium.Viewer('map', {
        infoBox: false,
      })
      /* 在 Cesium.js 中,MaterialProperty(材质属性)是用于定义材质在时间和空间上变化的动态属性。
       它提供了一种机制,可以根据时间、位置、实时数据等动态因素来控制材质的外观效果。 */
      class ConsumerMaterialProperty {
        constructor() {
          /* 获取每当此属性的定义更改时引发的事件。
          通用实用程序类,用于管理特定事件的订户。此类通常在容器类内部实例化,公开作为财产供其他人订阅。
          */
          this.definitionChanged = new Cesium.Event()
          this.myArg1Copy = null
          this.addMaterial()
        }
        addMaterial() {
          // 它用于在 Cesium 中的材质缓存中添加新的材质。
          Cesium.Material._materialCache.addMaterial('ConsumerMaterial', {
            fabric: {
              type: 'ConsumerMaterial',
              uniforms: {},
              source: `      
		czm_material czm_getMaterial(czm_materialInput materialInput)
	{
		czm_material material = czm_getDefaultMaterial(materialInput);
		material.diffuse = vec3(materialInput.st,0);
		return material;
	}`,
            },
          })
        }
        eventhandle(arg1) {
          console.log('监听事件被调用')
          this.myArg1Copy = arg1
        }
        getType(time) {
          // 返回材质类型
          // console.log('返回类型')
          return 'ConsumerMaterial'
        }
        getValue(time, result) {
          // 返回材质值
          // console.log('返回值', result)
          return result
        }
      }
      const material = new ConsumerMaterialProperty()
      // 调用类里面的事件
      material.definitionChanged.addEventListener(material.eventhandle, material)
      material.definitionChanged.raiseEvent('1')
      // 移除事件监听
      material.definitionChanged.removeEventListener(material.eventhandle)
      const entity = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0, 100000),
        ellipse: {
          semiMajorAxis: 200,
          semiMinorAxis: 200,
          height: 0, //离地面的高度
          material: material, //添加材质
        },
      })
      console.log(material, 'material')
      viewer.zoomTo(entity)
    </script>
  </body>
</html>

1. 在类内部创建事件

通用实用程序类,用于管理特定事件的订户。此类通常在容器类内部实例化,公开作为财产供其他人订阅。

MyObject.prototype.myListener = function(arg1, arg2) {
    this.myArg1Copy = arg1;
    this.myArg2Copy = arg2;
}

var myObjectInstance = new MyObject();
var evt = new Cesium.Event();
evt.addEventListener(MyObject.prototype.myListener, myObjectInstance);
evt.raiseEvent('1', '2');
evt.removeEventListener(MyObject.prototype.myListener);

// 这是Cesium官网的事件例子

2. 通过type获取自定义材质

MaterialProperty.getValue = function (time, materialProperty, material) {
  let type;

  if (defined(materialProperty)) {
   // 获取类型
    type = materialProperty.getType(time);
    if (defined(type)) {
      if (!defined(material) || material.type !== type) {
       // 通过类型获取材质
        material = Material.fromType(type);
      }
      materialProperty.getValue(time, material.uniforms);
      // 返回材质
      return material;
    }
  }

  if (!defined(material) || material.type !== Material.ColorType) {
    material = Material.fromType(Material.ColorType);
  }
  Color.clone(Color.WHITE, material.uniforms.color);

  return material;
};
Material.fromType = function (type, uniforms) {
  //>>includeStart('debug', pragmas.debug);
  if (!defined(Material._materialCache.getMaterial(type))) {
    throw new DeveloperError(`material with type '${type}' does not exist.`);
  }
  //>>includeEnd('debug');

  const material = new Material({
    fabric: {
      type: type,
    },
  });

  if (defined(uniforms)) {
    for (const name in uniforms) {
      if (uniforms.hasOwnProperty(name)) {
        material.uniforms[name] = uniforms[name];
      }
    }
  }

  return material;
};
  getMaterial: function(e) {
            return this._materials[e]
        }
    };

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值