Billboard Cloud

这是 OpenGL 课程的最终团队项目——互动式广告牌云。我们不仅实现了论文中的原始想法,还发展了自己的改进思路。通过使用多个广告牌来表示复杂的物体,例如树木,并采用三角形投影等技术细节,使算法更加高效和直观。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

This is the final project for my OpenGL class, which is a group work.

We not only implement the original idea of the paper, and we also develop our own ideas as improvements.

The basic idea of Billboard Cloud is quite simple: using multiple billboards to represent a complex object, as a tree. The key to this algorithm is projection of triangles. The idea in paper is to project the nearest triangles to a billboard.

We have made our new algorithm interactive. You can indicate the ratio (num. of boards / num. of triangles) or board number, so that you can see the difference interactively. Of course, we have to eliminate the constrains for distance (nearest triangles).

The picture below shows our work:

billboard 
(Picture generated by our project)

The technique detail: rendering of billboard adopts Texture capturing and Alpha-Testing in OpenGL.

watch(selectTowerId, (newVal, oldVal) => { if (oldVal && viewer.entities.getById('billboard' + oldVal + 'gltf')) { viewer.entities.getById('billboard' + oldVal + 'gltf').billboard.image = p1; } if (oldVal && viewer.entities.getById('billboard' + oldVal + 'tile')) { viewer.entities.getById('billboard' + oldVal + 'tile').billboard.image = p1; } if (newVal && viewer.entities.getById('billboard' + newVal + 'gltf') && nowModelType.value == 'gltf') { viewer.entities.getById('billboard' + newVal + 'gltf').billboard.image = p2 let data = getPositionById(newVal + 'gltf') let flyToPosition = Cesium.Cartesian3.fromDegrees( data[0], data[1] - 0.002, 130 ); viewer.camera.flyTo({ destination: flyToPosition, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-10), roll: Cesium.Math.toRadians(0), }, duration: 2, // 飞行持续时间 complete: function callback() { // 定位完成之后的回调函数 }, }); } else if (newVal && viewer.entities.getById('billboard' + newVal + 'tile')) { viewer.entities.getById('billboard' + newVal + 'tile').billboard.image = p2 let data = getPositionById('billboard' + newVal + 'tile') let flyToPosition = Cesium.Cartesian3.fromDegrees( data[0], data[1] - 0.002, 130 ); viewer.camera.flyTo({ destination: flyToPosition, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-10), roll: Cesium.Math.toRadians(0), }, duration: 2, // 飞行持续时间 complete: function callback() { // 定位完成之后的回调函数 }, }); } if (newVal && nowModelType.value == 'pointCloud' && viewer.entities.getById('billboard' + newVal)) { viewer.entities.getById('billboard' + newVal).billboard.image = img2 allTiles.forEach((item) => { if (item.id == newVal + 'tile') { // 获取tileset的边界球体中心点坐标 let { longitude, latitude, radius } = getTilesPosition(item.tileset); viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees( longitude, latitude - 0.002, radius + 50 + Number(item.elevation) ), orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-15), roll: Cesium.Math.toRadians(0), }, duration: 2, // 飞行持续时间 complete: function callback() { // 定位完成之后的回调函数 }, }); } }); } if (newVal && (!viewer.entities.getById('billboard' + newVal + 'gltf') && !viewer.entities.getById('billboard' + newVal + 'tile'))) { ElMessage({ message: "缺失模型数据!", grouping: true, type: "warning", offset: 200, }) } }); 优化代码
最新发布
07-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值