mirror of https://gitee.com/antv-l7/antv-l7
Shihui dev (#796)
* feat: add getModelMatrix into viewport * feat: 新增地球模式 (初步构建) * feat: 完善地球交互 * style: lint style * feat: 调整地球图层缩放的方向 * style: lint style * feat: 增加地球模式的 pointLayer/fill 图层 * style: lint style * feat: 增加地球、太阳的简单运动系统,优化部分代码结构 * fix: 修复时间点击出错 * style: lint style * fix: 修复地图 panBy 方法参数错误 * style: lint style * feat: pointLayer/cylinder 圆柱兼容地球模式 * style: lint style * feat: 修复 pointLayer/fill 在拾取是破面严重的情况 * style: lint style * feat: 增加 arc 弧度调节 * feat: 增加 lineLayer/arc3d 兼容地球模式 * style: lint style * feat: 增加地球图层 - 大气层 * style: lint style * feat: 增加设置可视化层背景色的能力 * style: lint style * feat: 增加地球外发光效果 * style: lint style * feat: 允许用户不使用 layer 的 source 方法 - 地球模式下光晕图层不需要传数据 * style: lint style * feat: 调整光晕的 shader 计算
This commit is contained in:
parent
cb792d4a77
commit
b296595858
|
@ -5,6 +5,7 @@ import earcut from 'earcut';
|
|||
import { mat4, vec3 } from 'gl-matrix';
|
||||
import {
|
||||
EARTH_RADIUS,
|
||||
EARTH_RADIUS_OUTER,
|
||||
EARTH_SEGMENTS,
|
||||
lglt2xyz,
|
||||
primitiveSphere,
|
||||
|
@ -415,3 +416,16 @@ export function earthTriangulation() {
|
|||
normals: normalArr,
|
||||
};
|
||||
}
|
||||
|
||||
export function earthOuterTriangulation() {
|
||||
const earthmesh = primitiveSphere(EARTH_RADIUS + EARTH_RADIUS_OUTER, {
|
||||
segments: EARTH_SEGMENTS,
|
||||
});
|
||||
const { positionsArr, indicesArr, normalArr } = earthmesh;
|
||||
return {
|
||||
vertices: positionsArr,
|
||||
indices: indicesArr,
|
||||
size: 5,
|
||||
normals: normalArr,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
import BaseLayer from '../core/BaseLayer';
|
||||
import EarthAtomSphereModel from './models/atmosphere';
|
||||
import BaseEarthModel from './models/base';
|
||||
import EarthBloomSphereModel from './models/bloomsphere';
|
||||
|
||||
interface IEarthLayerStyleOptions {
|
||||
opacity: number;
|
||||
setEarthTime(time: number): void;
|
||||
}
|
||||
|
||||
export type EarthModelType = 'base' | 'atomSphere';
|
||||
export type EarthModelType = 'base' | 'atomSphere' | 'bloomSphere';
|
||||
|
||||
const EarthModels: { [key in EarthModelType]: any } = {
|
||||
base: BaseEarthModel,
|
||||
atomSphere: EarthAtomSphereModel,
|
||||
bloomSphere: EarthBloomSphereModel,
|
||||
};
|
||||
|
||||
const earthLayerTypes = ['base', 'atomSphere'];
|
||||
const earthLayerTypes = ['base', 'atomSphere', 'bloomSphere'];
|
||||
|
||||
export default class EarthLayer extends BaseLayer<IEarthLayerStyleOptions> {
|
||||
public type: string = 'EarthLayer';
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
import {
|
||||
AttributeType,
|
||||
BlendType,
|
||||
gl,
|
||||
IEncodeFeature,
|
||||
ILayerConfig,
|
||||
IModel,
|
||||
IModelUniform,
|
||||
ITexture2D,
|
||||
} from '@antv/l7-core';
|
||||
import { rgb2arr } from '@antv/l7-utils';
|
||||
import { isNumber } from 'lodash';
|
||||
|
||||
import BaseModel, { styleOffset, styleSingle } from '../../core/BaseModel';
|
||||
import BaseModel from '../../core/BaseModel';
|
||||
import { earthTriangulation } from '../../core/triangulation';
|
||||
import atmoSphereFrag from '../shaders/atmosphere_frag.glsl';
|
||||
import atmoSphereVert from '../shaders/atmosphere_vert.glsl';
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
import {
|
||||
AttributeType,
|
||||
gl,
|
||||
IEncodeFeature,
|
||||
IModel,
|
||||
IModelUniform,
|
||||
} from '@antv/l7-core';
|
||||
import { isNumber } from 'lodash';
|
||||
|
||||
import BaseModel from '../../core/BaseModel';
|
||||
import { earthOuterTriangulation } from '../../core/triangulation';
|
||||
import bloomSphereFrag from '../shaders/bloomsphere_frag.glsl';
|
||||
import bloomSphereVert from '../shaders/bloomsphere_vert.glsl';
|
||||
interface IBloomLayerStyleOptions {
|
||||
opacity: number;
|
||||
}
|
||||
|
||||
export default class EarthBloomSphereModel extends BaseModel {
|
||||
public getUninforms(): IModelUniform {
|
||||
const {
|
||||
opacity = 1,
|
||||
} = this.layer.getLayerConfig() as IBloomLayerStyleOptions;
|
||||
return {
|
||||
u_opacity: isNumber(opacity) ? opacity : 1.0,
|
||||
};
|
||||
}
|
||||
|
||||
public initModels(): IModel[] {
|
||||
return this.buildModels();
|
||||
}
|
||||
|
||||
public clearModels() {
|
||||
return '';
|
||||
}
|
||||
|
||||
public buildModels(): IModel[] {
|
||||
// TODO: 调整图层的绘制顺序,让它保持在地球后面(减少锯齿现象)
|
||||
this.layer.zIndex = -999;
|
||||
return [
|
||||
this.layer.buildLayerModel({
|
||||
moduleName: 'earthBloomSphere',
|
||||
vertexShader: bloomSphereVert,
|
||||
fragmentShader: bloomSphereFrag,
|
||||
triangulation: earthOuterTriangulation,
|
||||
depth: {
|
||||
enable: false,
|
||||
},
|
||||
blend: this.getBlend(),
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected registerBuiltinAttributes() {
|
||||
// point layer size;
|
||||
this.styleAttributeService.registerStyleAttribute({
|
||||
name: 'size',
|
||||
type: AttributeType.Attribute,
|
||||
descriptor: {
|
||||
name: 'a_Size',
|
||||
buffer: {
|
||||
// give the WebGL driver a hint that this buffer may change
|
||||
usage: gl.DYNAMIC_DRAW,
|
||||
data: [],
|
||||
type: gl.FLOAT,
|
||||
},
|
||||
size: 1,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
featureIdx: number,
|
||||
vertex: number[],
|
||||
attributeIdx: number,
|
||||
) => {
|
||||
const { size = 1 } = feature;
|
||||
return Array.isArray(size) ? [size[0]] : [size as number];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.styleAttributeService.registerStyleAttribute({
|
||||
name: 'normal',
|
||||
type: AttributeType.Attribute,
|
||||
descriptor: {
|
||||
name: 'a_Normal',
|
||||
buffer: {
|
||||
// give the WebGL driver a hint that this buffer may change
|
||||
usage: gl.STATIC_DRAW,
|
||||
data: [],
|
||||
type: gl.FLOAT,
|
||||
},
|
||||
size: 3,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
featureIdx: number,
|
||||
vertex: number[],
|
||||
attributeIdx: number,
|
||||
normal: number[],
|
||||
) => {
|
||||
return normal;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.styleAttributeService.registerStyleAttribute({
|
||||
name: 'uv',
|
||||
type: AttributeType.Attribute,
|
||||
descriptor: {
|
||||
name: 'a_Uv',
|
||||
buffer: {
|
||||
// give the WebGL driver a hint that this buffer may change
|
||||
usage: gl.DYNAMIC_DRAW,
|
||||
data: [],
|
||||
type: gl.FLOAT,
|
||||
},
|
||||
size: 2,
|
||||
update: (
|
||||
feature: IEncodeFeature,
|
||||
featureIdx: number,
|
||||
vertex: number[],
|
||||
attributeIdx: number,
|
||||
) => {
|
||||
return [vertex[3], vertex[4]];
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
|
||||
uniform float u_opacity;
|
||||
uniform vec3 u_CameraPosition;
|
||||
varying vec3 vVertexNormal;
|
||||
|
||||
varying vec3 vVertexNormal;
|
||||
varying float v_offset;
|
||||
varying vec4 v_Color;
|
||||
void main() {
|
||||
|
||||
|
||||
float intensity = pow(0.5 + dot(normalize(vVertexNormal), normalize(u_CameraPosition)), 3.0);
|
||||
|
||||
|
||||
// float intensity = pow(0.5 + dot(normalize(vVertexNormal), normalize(u_CameraPosition)), 3.0);
|
||||
float intensity = pow(v_offset + dot(normalize(vVertexNormal), normalize(u_CameraPosition)), 3.0);
|
||||
// TODO: 去除背面
|
||||
if(intensity > 1.0) intensity = 0.0;
|
||||
|
||||
|
|
|
@ -4,16 +4,22 @@ attribute vec3 a_Normal;
|
|||
attribute vec2 a_Uv;
|
||||
attribute vec4 a_Color;
|
||||
uniform vec3 u_CameraPosition;
|
||||
varying float v_CamreaDistance;
|
||||
|
||||
uniform mat4 u_ViewProjectionMatrix;
|
||||
uniform mat4 u_ModelMatrix;
|
||||
uniform mat4 u_ViewMatrix;
|
||||
|
||||
varying vec3 vVertexNormal;
|
||||
varying vec4 v_Color;
|
||||
varying float v_offset;
|
||||
|
||||
void main() {
|
||||
float EARTH_RADIUS = 100.0;
|
||||
|
||||
v_Color = a_Color;
|
||||
|
||||
v_offset = min(((length(u_CameraPosition) - EARTH_RADIUS)/600.0) * 0.5 + 0.4, 1.0);
|
||||
vVertexNormal = a_Normal;
|
||||
|
||||
gl_Position = u_ViewProjectionMatrix * u_ModelMatrix * vec4(a_Position, 1.0);
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
uniform float u_opacity;
|
||||
uniform vec3 u_CameraPosition;
|
||||
varying vec3 vVertexNormal;
|
||||
|
||||
varying vec4 v_Color;
|
||||
void main() {
|
||||
|
||||
|
||||
float intensity = - dot(normalize(vVertexNormal), normalize(u_CameraPosition));
|
||||
// TODO: 去除背面
|
||||
if(intensity > 1.0) intensity = 0.0;
|
||||
|
||||
gl_FragColor = vec4(v_Color.rgb, v_Color.a * intensity * u_opacity);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
attribute vec3 a_Position;
|
||||
attribute vec3 a_Normal;
|
||||
attribute vec2 a_Uv;
|
||||
attribute vec4 a_Color;
|
||||
uniform vec3 u_CameraPosition;
|
||||
uniform mat4 u_ViewProjectionMatrix;
|
||||
uniform mat4 u_ModelMatrix;
|
||||
uniform mat4 u_ViewMatrix;
|
||||
|
||||
varying vec3 vVertexNormal;
|
||||
varying vec4 v_Color;
|
||||
|
||||
void main() {
|
||||
v_Color = a_Color;
|
||||
|
||||
vVertexNormal = a_Normal;
|
||||
|
||||
gl_Position = u_ViewProjectionMatrix * u_ModelMatrix * vec4(a_Position, 1.0);
|
||||
}
|
|
@ -5,6 +5,8 @@ import { mat4, vec3 } from 'gl-matrix';
|
|||
export const EARTH_RADIUS = 100;
|
||||
export const EARTH_SEGMENTS = 36;
|
||||
|
||||
export const EARTH_RADIUS_OUTER = 40;
|
||||
|
||||
/**
|
||||
* 角度转弧度
|
||||
* @param deg
|
||||
|
|
|
@ -5,9 +5,8 @@ import {
|
|||
IMapService,
|
||||
TYPES,
|
||||
} from '@antv/l7-core';
|
||||
import Source from '@antv/l7-source';
|
||||
import Source, { DEFAULT_DATA, DEFAULT_PARSER } from '@antv/l7-source';
|
||||
import { injectable } from 'inversify';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import 'reflect-metadata';
|
||||
|
||||
@injectable()
|
||||
|
@ -18,7 +17,11 @@ export default class DataSourcePlugin implements ILayerPlugin {
|
|||
layer.hooks.init.tap('DataSourcePlugin', () => {
|
||||
const source = layer.getSource();
|
||||
if (!source) {
|
||||
const { data, options } = layer.sourceOption;
|
||||
// TODO: 允许用户不使用 layer 的 source 方法,在这里传入一个默认的替换的默认数据
|
||||
const { data, options } = layer.sourceOption || {
|
||||
data: DEFAULT_DATA,
|
||||
options: DEFAULT_PARSER,
|
||||
};
|
||||
layer.setSource(new Source(data, options));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { registerParser, registerTransform } from './factory';
|
|||
import csv from './parser/csv';
|
||||
import geojson from './parser/geojson';
|
||||
import image from './parser/image';
|
||||
import json from './parser/json';
|
||||
import json, { defaultData, defaultParser } from './parser/json';
|
||||
import raster from './parser/raster';
|
||||
import Source from './source';
|
||||
import { cluster } from './transform/cluster';
|
||||
|
@ -31,3 +31,6 @@ export {
|
|||
} from './factory';
|
||||
|
||||
export * from './interface';
|
||||
|
||||
export const DEFAULT_DATA = defaultData;
|
||||
export const DEFAULT_PARSER = defaultParser;
|
||||
|
|
|
@ -47,3 +47,23 @@ export default function json(data: IJsonData, cfg: IParserCfg): IParserData {
|
|||
dataArray: resultData,
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: 提供默认数据和解析器
|
||||
export const defaultData = [
|
||||
{
|
||||
lng1: 100,
|
||||
lat1: 30.0,
|
||||
lng2: 130,
|
||||
lat2: 30,
|
||||
},
|
||||
];
|
||||
|
||||
export const defaultParser = {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng1',
|
||||
y: 'lat1',
|
||||
x1: 'lng2',
|
||||
y1: 'lat2',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -122,29 +122,17 @@ export default class ScaleComponent extends React.Component {
|
|||
// earthlayer.setEarthTime(4.0)
|
||||
|
||||
const atomLayer = new EarthLayer()
|
||||
.source(
|
||||
[
|
||||
{
|
||||
lng1: 100,
|
||||
lat1: 30.0,
|
||||
lng2: 130,
|
||||
lat2: 30,
|
||||
},
|
||||
],
|
||||
{
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng1',
|
||||
y: 'lat1',
|
||||
x1: 'lng2',
|
||||
y1: 'lat2',
|
||||
},
|
||||
},
|
||||
)
|
||||
.color('#2E8AE6')
|
||||
.shape('atomSphere')
|
||||
.style({
|
||||
opacity: 1.5,
|
||||
opacity: 1,
|
||||
});
|
||||
|
||||
const bloomLayer = new EarthLayer()
|
||||
.color('#fff')
|
||||
.shape('bloomSphere')
|
||||
.style({
|
||||
opacity: 0.5,
|
||||
});
|
||||
|
||||
scene.on('loaded', () => {
|
||||
|
@ -154,6 +142,7 @@ export default class ScaleComponent extends React.Component {
|
|||
|
||||
// earthlayer.setEarthTime(4.0);
|
||||
scene.addLayer(atomLayer);
|
||||
scene.addLayer(bloomLayer);
|
||||
scene.addLayer(lineLayer);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue