Skip to content

Commit

Permalink
feat: support terrain block & zoomTo
Browse files Browse the repository at this point in the history
  • Loading branch information
hongfaqiu committed Oct 25, 2024
1 parent 0a79d1e commit e443602
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 85 deletions.
78 changes: 58 additions & 20 deletions example/src/components/ControlPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { QuestionCircleOutlined } from '@ant-design/icons';
import ColorTableInput from './ColorTableInput';
import styled from 'styled-components';
import { GithubOutlined } from '@ant-design/icons';
import { ZoomInOutlined } from '@ant-design/icons';

const { Text } = Typography;

Expand Down Expand Up @@ -125,13 +126,10 @@ const CardTitle = styled.div`
&:hover {
opacity: 0.8;
}
span {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
`;

const TitleText = styled.span`
flex: 1;
`;

const ControlPanelContainer = styled.div`
Expand Down Expand Up @@ -210,6 +208,35 @@ const GithubLink = () => (
</GithubBadge>
);

const TitleActions = styled.div`
display: flex;
align-items: center;
gap: 8px;
`;

const TitleButton = styled.button`
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
padding: 0;
background: transparent;
border: none;
cursor: pointer;
color: rgba(0, 0, 0, 0.45);
transition: all 0.3s;
&:hover {
color: rgba(0, 0, 0, 0.85);
background: rgba(0, 0, 0, 0.04);
}
&:active {
background: rgba(0, 0, 0, 0.08);
}
`;

interface ControlPanelProps {
windLayer: WindLayer | null;
initialOptions?: Partial<WindLayerOptions>;
Expand All @@ -231,7 +258,7 @@ export const ControlPanel: React.FC<ControlPanelProps> = ({
...WindLayer.defaultOptions,
...initialOptions,
});
}, [windLayer]);
}, [windLayer, initialOptions]);

const renderLabel = (label: string, tooltip: string) => (
<div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
Expand All @@ -257,17 +284,28 @@ export const ControlPanel: React.FC<ControlPanelProps> = ({
<StyledCard
title={
<CardTitle onClick={() => setCollapsed(!collapsed)}>
<span>Wind Layer Controls</span>
<CollapseButton $collapsed={collapsed}>
<svg
viewBox="0 0 24 24"
width="12"
height="12"
fill="currentColor"
<TitleText>Wind Layer Controls</TitleText>
<TitleActions>
<TitleButton
onClick={(e) => {
e.stopPropagation();
windLayer?.zoomTo(1);
}}
title="Zoom to Wind Field"
>
<path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" />
</svg>
</CollapseButton>
<ZoomInOutlined />
</TitleButton>
<CollapseButton $collapsed={collapsed}>
<svg
viewBox="0 0 24 24"
width="12"
height="12"
fill="currentColor"
>
<path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" />
</svg>
</CollapseButton>
</TitleActions>
</CardTitle>
}
size="small"
Expand Down Expand Up @@ -302,7 +340,7 @@ export const ControlPanel: React.FC<ControlPanelProps> = ({
'Height of particles above the ground in meters.'
)}
>
<Slider min={0} max={100000} step={100} />
<Slider min={-1000} max={10000} step={100} />
</CompactFormItem>

<CompactFormItem
Expand All @@ -312,7 +350,7 @@ export const ControlPanel: React.FC<ControlPanelProps> = ({
'Width of particle trails in pixels. Controls the width of the particles.'
)}
>
<Slider min={1} max={10} step={0.5} />
<Slider min={0.1} max={10} step={0.1} />
</CompactFormItem>

<CompactFormItem
Expand Down
14 changes: 13 additions & 1 deletion example/src/pages/earth.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { useEffect, useRef, useState } from 'react';
import { Viewer, Rectangle, ArcGisMapServerImageryProvider, ImageryLayer } from 'cesium';
import { Viewer, Rectangle, ArcGisMapServerImageryProvider, ImageryLayer, Ion, CesiumTerrainProvider } from 'cesium';
import { WindLayer, WindLayerOptions, WindData } from 'cesium-wind-layer';
import { ControlPanel } from '@/components/ControlPanel';
import styled from 'styled-components';
import { colorSchemes } from '@/components/ColorTableInput';

Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhY2IzNzQzNi1iOTVkLTRkZjItOWVkZi1iMGUyYTUxN2Q5YzYiLCJpZCI6NTUwODUsImlhdCI6MTcyNTQyMDE4NX0.yHbHpszFexPrxX6_55y0RgNrHjBQNu9eYkW9cXKUTPk';

const CesiumContainer = styled.div`
width: 100vw;
height: 100vh;
Expand All @@ -14,6 +16,7 @@ const CesiumContainer = styled.div`
const defaultOptions: Partial<WindLayerOptions> = {
particlesTextureSize: 200,
dropRate: 0.003,
particleHeight: 1000,
dropRateBump: 0.01,
speedFactor: 10.0,
lineWidth: 3.0,
Expand Down Expand Up @@ -50,7 +53,16 @@ export function Earth() {
sceneModePicker: true,
});
}
// Add terrain
CesiumTerrainProvider.fromIonAssetId(1).then(terrainProvider => {
if (viewerRef.current) {
viewerRef.current.terrainProvider = terrainProvider;
}
});

viewerRef.current.scene.globe.depthTestAgainstTerrain = true;
// Optional: Add exaggeration to make terrain features more visible
viewerRef.current.scene.verticalExaggeration = 2;
// Load wind data
const loadWindData = async () => {
// Skip if wind layer already exists or viewer is not initialized
Expand Down
8 changes: 6 additions & 2 deletions packages/cesium-wind-layer/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ A Cesium plugin for GPU-accelerated visualization of wind field data with partic

[中文文档](/packages/cesium-wind-layer/readme.zh-CN.md) | [Live Demo](https://cesium-wind-layer.opendde.com/)

![Wind Layer Demo](/pictures/wind.gif)
<div style="display: flex; justify-content: space-between;">
<img src="/pictures/wind.gif" alt="Wind Layer Demo" style="width: 48%;">
<img src="/pictures/terrain.gif" alt="Terrain Demo" style="width: 48%;">
</div>

## 📚 Table of Contents

Expand All @@ -23,7 +26,7 @@ A Cesium plugin for GPU-accelerated visualization of wind field data with partic
- 🚀 GPU-accelerated particle computation and rendering
- 🎨 Customizable particle appearance and behavior
- 🌍 Support for both 2D and 3D views
- 🔄 Compatible with Cesium 3D globe
- 🏔️ Terrain occlusion support, particles are blocked by terrain

## 📦 Installation

Expand Down Expand Up @@ -107,6 +110,7 @@ interface WindLayerOptions {
| `show: boolean` | Get or set the visibility of the wind layer |
| `updateWindData(data: WindData)` | Update the wind field data |
| `updateOptions(options: Partial<WindLayerOptions>)` | Update the options of the wind layer |
| `zoomTo(duration?: number)` | Zoom the camera to fit the wind field extent |
| `isDestroyed(): boolean` | Check if the wind layer has been destroyed |
| `destroy()` | Clean up resources and destroy the wind layer |

Expand Down
8 changes: 6 additions & 2 deletions packages/cesium-wind-layer/readme.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

[English](/packages/cesium-wind-layer/readme.md) | [在线演示](https://cesium-wind-layer.opendde.com/)

![Wind Layer Demo](/pictures/wind.gif)
<div style="display: flex; justify-content: space-between;">
<img src="/pictures/wind.gif" alt="Wind Layer Demo" style="width: 48%;">
<img src="/pictures/terrain.gif" alt="Terrain Demo" style="width: 48%;">
</div>

## 📚 目录

Expand All @@ -23,7 +26,7 @@
- 🚀 GPU 加速的粒子计算和渲染
- 🎨 可自定义粒子外观和行为
- 🌍 支持 2D 和 3D 视图
- 🔄 兼容 Cesium 3D 地球
- 🏔️ 支持地形遮挡,粒子会被地形阻挡

## 📦 安装

Expand Down Expand Up @@ -107,6 +110,7 @@ interface WindLayerOptions {
| `show: boolean` | 获取或设置风场图层的可见性 |
| `updateWindData(data: WindData)` | 更新风场数据 |
| `updateOptions(options: Partial<WindLayerOptions>)` | 更新风场图层的选项 |
| `zoomTo(duration?: number)` | 缩放相机以适应风场范围 |
| `isDestroyed(): boolean` | 检查风场图层是否已被销毁 |
| `destroy()` | 清理资源并销毁风场图层 |

Expand Down
18 changes: 17 additions & 1 deletion packages/cesium-wind-layer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
BoundingSphere,
Ellipsoid,
SceneMode,
Math as CesiumMath
Math as CesiumMath,
Rectangle
} from 'cesium';

import { WindLayerOptions, WindData } from './types';
Expand Down Expand Up @@ -193,6 +194,21 @@ export class WindLayer {
this.viewer.scene.requestRender();
}

zoomTo(duration: number = 0): void {
if (this.windData.bounds) {
const rectangle = Rectangle.fromDegrees(
this.windData.bounds.west,
this.windData.bounds.south,
this.windData.bounds.east,
this.windData.bounds.north
);
this.viewer.camera.flyTo({
destination: rectangle,
duration,
});
}
}

add(): void {
this.primitives = this.particleSystem.getPrimitives();
this.primitives.forEach(primitive => {
Expand Down
15 changes: 0 additions & 15 deletions packages/cesium-wind-layer/src/shaderManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { updatePositionShader } from './shaders/updatePosition';
import { calculateSpeedShader } from './shaders/calculateSpeed';
import { postProcessingPositionFragmentShader } from './shaders/postProcessingPosition';
import { renderParticlesFragmentShader, renderParticlesVertexShader } from './shaders/segmentDraw';
import { fullscreenQuadVertexShader } from './shaders/fullscreenQuad';
import { screenDrawFragmentShader } from './shaders/screenDraw';

export class ShaderManager {
static getCalculateSpeedShader(): ShaderSource {
Expand Down Expand Up @@ -37,17 +35,4 @@ export class ShaderManager {
});
}

static getFullscreenQuadVertexShader(): ShaderSource {
return new ShaderSource({
defines: ['DISABLE_GL_POSITION_LOG_DEPTH'],
sources: [fullscreenQuadVertexShader]
});
}

static getScreenDrawFragmentShader(): ShaderSource {
return new ShaderSource({
defines: ['DISABLE_LOG_DEPTH_FRAGMENT_WRITE'],
sources: [screenDrawFragmentShader]
});
}
}
12 changes: 0 additions & 12 deletions packages/cesium-wind-layer/src/shaders/fullscreenQuad.ts

This file was deleted.

20 changes: 0 additions & 20 deletions packages/cesium-wind-layer/src/shaders/screenDraw.ts

This file was deleted.

Loading

0 comments on commit e443602

Please sign in to comment.