Shihui dev (#790)

* 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 弧度调节
This commit is contained in:
YiQianYao 2021-10-09 17:50:27 +08:00 committed by GitHub
parent 7599dc85c7
commit 02df900784
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 57 additions and 41 deletions

View File

@ -15,4 +15,5 @@ export interface ILineLayerStyleOptions {
textureBlend?: string; // 可选参数、供给纹理贴图使用(all) textureBlend?: string; // 可选参数、供给纹理贴图使用(all)
sourceColor?: string; // 可选参数、设置渐变色的起始颜色(all) sourceColor?: string; // 可选参数、设置渐变色的起始颜色(all)
targetColor?: string; // 可选参数、设置渐变色的终点颜色(all) targetColor?: string; // 可选参数、设置渐变色的终点颜色(all)
thetaOffset?: number; // 可选参数、设置弧线的偏移量
} }

View File

@ -24,9 +24,12 @@ export function lglt2xyz(lnglat: [number, number]) {
const lng = torad(lnglat[0]) + Math.PI / 2; const lng = torad(lnglat[0]) + Math.PI / 2;
const lat = torad(lnglat[1]); const lat = torad(lnglat[1]);
const z = EARTH_RADIUS * Math.cos(lat) * Math.cos(lng); // TODO: 手动增加一些偏移,减轻面的冲突
const x = EARTH_RADIUS * Math.cos(lat) * Math.sin(lng); const radius = EARTH_RADIUS + Math.random() * 0.4;
const y = EARTH_RADIUS * Math.sin(lat);
const z = radius * Math.cos(lat) * Math.cos(lng);
const x = radius * Math.cos(lat) * Math.sin(lng);
const y = radius * Math.sin(lat);
return [x, y, z]; return [x, y, z];
} }

View File

@ -34,6 +34,7 @@ export default class ArcModel extends BaseModel {
lineTexture = false, lineTexture = false,
iconStep = 100, iconStep = 100,
segmentNumber = 30, segmentNumber = 30,
thetaOffset = 0.314,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions; } = this.layer.getLayerConfig() as ILineLayerStyleOptions;
if (this.dataTextureTest && this.dataTextureNeedUpdate({ opacity })) { if (this.dataTextureTest && this.dataTextureNeedUpdate({ opacity })) {
@ -85,6 +86,7 @@ export default class ArcModel extends BaseModel {
} }
return { return {
u_thetaOffset: thetaOffset,
u_dataTexture: this.dataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1] u_dataTexture: this.dataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1]
u_cellTypeLayout: this.getCellTypeLayout(), u_cellTypeLayout: this.getCellTypeLayout(),

View File

@ -19,6 +19,7 @@ uniform vec4 u_dash_array: [10.0, 5., 0, 0];
uniform float u_lineDir: 1.0; uniform float u_lineDir: 1.0;
varying vec4 v_dash_array; varying vec4 v_dash_array;
uniform float u_thetaOffset: 0.314;
uniform float u_icon_step: 100; uniform float u_icon_step: 100;
uniform float u_line_texture: 0.0; uniform float u_line_texture: 0.0;
attribute vec2 a_iconMapUV; attribute vec2 a_iconMapUV;
@ -41,36 +42,10 @@ float bezier3(vec3 arr, float t) {
return (arr.x * ut + arr.y * t) * ut + (arr.y * ut + arr.z * t) * t; return (arr.x * ut + arr.y * t) * ut + (arr.y * ut + arr.z * t) * t;
} }
vec2 midPoint(vec2 source, vec2 target) { vec2 midPoint(vec2 source, vec2 target) {
// cal style mapping - 数据纹理映射部分的计算
styleMappingMat = mat4(
0.0, 0.0, 0.0, 0.0, // opacity - strokeOpacity - strokeWidth - empty
0.0, 0.0, 0.0, 0.0, // strokeR - strokeG - strokeB - strokeA
0.0, 0.0, 0.0, 0.0, // offsets[0] - offsets[1]
0.0, 0.0, 0.0, 0.0
);
float rowCount = u_cellTypeLayout[0][0]; // 当前的数据纹理有几行
float columnCount = u_cellTypeLayout[0][1]; // 当看到数据纹理有几列
float columnWidth = 1.0/columnCount; // 列宽
float rowHeight = 1.0/rowCount; // 行高
float cellCount = calCellCount(); // opacity - strokeOpacity - strokeWidth - stroke - offsets
float id = a_vertexId; // 第n个顶点
float cellCurrentRow = floor(id * cellCount / columnCount) + 1.0; // 起始点在第几行
float cellCurrentColumn = mod(id * cellCount, columnCount) + 1.0; // 起始点在第几列
// cell 固定顺序 opacity -> strokeOpacity -> strokeWidth -> stroke ...
// 按顺序从 cell 中取值、若没有则自动往下取值
float textureOffset = 0.0; // 在 cell 中取值的偏移量
vec2 opacityAndOffset = calOpacityAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight);
styleMappingMat[0][0] = opacityAndOffset.r;
textureOffset = opacityAndOffset.g;
// cal style mapping - 数据纹理映射部分的计算
vec2 center = target - source; vec2 center = target - source;
float r = length(center); float r = length(center);
float theta = atan(center.y, center.x); float theta = atan(center.y, center.x);
float thetaOffset = 0.314; float thetaOffset = u_thetaOffset;
float r2 = r / 2.0 / cos(thetaOffset); float r2 = r / 2.0 / cos(thetaOffset);
float theta2 = theta + thetaOffset; float theta2 = theta + thetaOffset;
vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y); vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y);
@ -112,6 +87,33 @@ vec2 getNormal(vec2 line_clipspace, float offset_direction) {
void main() { void main() {
v_color = a_Color; v_color = a_Color;
// cal style mapping - 数据纹理映射部分的计算
styleMappingMat = mat4(
0.0, 0.0, 0.0, 0.0, // opacity - strokeOpacity - strokeWidth - empty
0.0, 0.0, 0.0, 0.0, // strokeR - strokeG - strokeB - strokeA
0.0, 0.0, 0.0, 0.0, // offsets[0] - offsets[1]
0.0, 0.0, 0.0, 0.0
);
float rowCount = u_cellTypeLayout[0][0]; // 当前的数据纹理有几行
float columnCount = u_cellTypeLayout[0][1]; // 当看到数据纹理有几列
float columnWidth = 1.0/columnCount; // 列宽
float rowHeight = 1.0/rowCount; // 行高
float cellCount = calCellCount(); // opacity - strokeOpacity - strokeWidth - stroke - offsets
float id = a_vertexId; // 第n个顶点
float cellCurrentRow = floor(id * cellCount / columnCount) + 1.0; // 起始点在第几行
float cellCurrentColumn = mod(id * cellCount, columnCount) + 1.0; // 起始点在第几列
// cell 固定顺序 opacity -> strokeOpacity -> strokeWidth -> stroke ...
// 按顺序从 cell 中取值、若没有则自动往下取值
float textureOffset = 0.0; // 在 cell 中取值的偏移量
vec2 opacityAndOffset = calOpacityAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight);
styleMappingMat[0][0] = opacityAndOffset.r;
textureOffset = opacityAndOffset.g;
// cal style mapping - 数据纹理映射部分的计算
vec2 source = a_Instance.rg; // 起始点 vec2 source = a_Instance.rg; // 起始点
vec2 target = a_Instance.ba; // 终点 vec2 target = a_Instance.ba; // 终点
float segmentIndex = a_Position.x; float segmentIndex = a_Position.x;

View File

@ -1,5 +1,6 @@
#define Animate 0.0 #define Animate 0.0
uniform float u_globel;
uniform float u_blur : 0; uniform float u_blur : 0;
// uniform float u_stroke_width : 1; // uniform float u_stroke_width : 1;
@ -68,7 +69,14 @@ void main() {
inner_df = sdVesica(v_data.xy, r * 1.1, r * 0.8); inner_df = sdVesica(v_data.xy, r * 1.1, r * 0.8);
} }
if(u_globel > 0.0) {
// TODO: 地球模式下避免多余片元绘制,同时也能避免有用片元在透明且重叠的情况下无法写入
// 付出的代价是边缘会有一些锯齿
if(outer_df > antialiased_blur + 0.018) discard;
}
float opacity_t = smoothstep(0.0, antialiased_blur, outer_df); float opacity_t = smoothstep(0.0, antialiased_blur, outer_df);
// float color_t = u_stroke_width < 0.01 ? 0.0 : smoothstep( // float color_t = u_stroke_width < 0.01 ? 0.0 : smoothstep(
// antialiased_blur, // antialiased_blur,
// 0.0, // 0.0,
@ -85,7 +93,6 @@ void main() {
gl_FragColor = mix(vec4(v_color.rgb, v_color.a * opacity), strokeColor * stroke_opacity, color_t); gl_FragColor = mix(vec4(v_color.rgb, v_color.a * opacity), strokeColor * stroke_opacity, color_t);
gl_FragColor.a = gl_FragColor.a * opacity_t; gl_FragColor.a = gl_FragColor.a * opacity_t;
if(u_aimate.x == Animate) { if(u_aimate.x == Animate) {
float d = length(v_data.xy); float d = length(v_data.xy);
@ -93,9 +100,8 @@ void main() {
gl_FragColor = vec4(gl_FragColor.xyz, intensity); gl_FragColor = vec4(gl_FragColor.xyz, intensity);
} }
// TODO: 避免多余片元绘制,同时也能避免有用片元在透明且重叠的情况下无法写入
if(gl_FragColor.a <= 0.0) discard;
gl_FragColor = filterColor(gl_FragColor); gl_FragColor = filterColor(gl_FragColor);
} }

View File

@ -66,6 +66,7 @@ export default class Amap2demo_arcLineLinear extends React.Component {
// textureBlend: 'normal', // textureBlend: 'normal',
sourceColor: '#f00', sourceColor: '#f00',
targetColor: '#0f0', targetColor: '#0f0',
// thetaOffset: 0.5
}); });
// .animate({ // .animate({
// duration: 50, // duration: 50,

View File

@ -22,6 +22,7 @@ export default class ScaleComponent extends React.Component {
}); });
var d = [ var d = [
{ lng: 110, lat: 30 },
{ lng: 127.657407, lat: 49.76027 }, { lng: 127.657407, lat: 49.76027 },
{ lng: 129.397818, lat: 49.4406 }, { lng: 129.397818, lat: 49.4406 },
{ lng: 130.582293, lat: 48.729687 }, { lng: 130.582293, lat: 48.729687 },
@ -351,15 +352,15 @@ export default class ScaleComponent extends React.Component {
}, },
}, },
) )
// .shape('circle') .shape('circle')
.shape('cylinder') // .shape('cylinder')
.color('#f00') .color('#f00')
.size('', () => [1, 1, 10]) // .size('', () => [1, 1, 10])
// .size(20) .size(20)
.style({ .style({
// opacity: 0.6, // opacity: 0.6,
}) })
.animate(true) // .animate(true)
.active(true); .active(true);
// scene.addLayer(pointlayer); // scene.addLayer(pointlayer);
@ -406,8 +407,8 @@ export default class ScaleComponent extends React.Component {
// earthTime: 4.0 // earthTime: 4.0
earthTime: 0.1, earthTime: 0.1,
}, },
}) });
.animate(true); // .animate(true);
// earthlayer.setEarthTime(4.0) // earthlayer.setEarthTime(4.0)
scene.on('loaded', () => { scene.on('loaded', () => {
scene.addLayer(earthlayer); scene.addLayer(earthlayer);