sync
This commit is contained in:
parent
0836c004eb
commit
6d6836a83f
@ -1,9 +1,11 @@
|
||||
use glow::HasContext;
|
||||
use log::*;
|
||||
use radarg_core::{CoordType, ProbeDataType, RadarGridData};
|
||||
|
||||
use crate::{
|
||||
components::{Program, Shader},
|
||||
errors::*,
|
||||
match_array_type,
|
||||
pg::Attach,
|
||||
shaders::geoquadmesh::{GeoQuadMeshFragment, GeoQuadMeshVertex},
|
||||
};
|
||||
@ -33,7 +35,7 @@ impl GeoQuadMesh {
|
||||
let lat_dpi = config.lat_dpi;
|
||||
let alt_dpi = config.alt_dpi;
|
||||
|
||||
let location = self.program.get_uniform_location(gl, "data_info");
|
||||
let data_info = self.program.get_uniform_location(gl, "data_info");
|
||||
|
||||
self.cmap
|
||||
.set_range(config.color_range[0], config.color_range[1]);
|
||||
@ -44,10 +46,16 @@ impl GeoQuadMesh {
|
||||
let location_r = self.program.get_uniform_location(gl, "R");
|
||||
let location_layer = self.program.get_uniform_location(gl, "layer");
|
||||
let tex_conf = self.program.get_uniform_location(gl, "tex_conf");
|
||||
let data_shape = self.program.get_uniform_location(gl, "data_shape");
|
||||
let dpi = self.program.get_uniform_location(gl, "dpi");
|
||||
|
||||
unsafe {
|
||||
let offset = config.offset;
|
||||
let scale = config.scale;
|
||||
let min = config.min;
|
||||
let max = config.max;
|
||||
gl.uniform_1_f32(location_r.as_ref(), 6378137.0);
|
||||
gl.uniform_4_f32(location.as_ref(), lon_dpi, lat_dpi, alt_dpi, 0.0);
|
||||
gl.uniform_4_f32(data_info.as_ref(), offset, scale, min, max);
|
||||
gl.uniform_1_f32(location_layer.as_ref(), config.layer as f32);
|
||||
|
||||
let lon_s = config.lon_range[0];
|
||||
@ -55,6 +63,11 @@ impl GeoQuadMesh {
|
||||
let lat_s = config.lat_range[0];
|
||||
let lat_e = config.lat_range[1];
|
||||
gl.uniform_4_f32(tex_conf.as_ref(), lon_s, lon_e, lat_s, lat_e);
|
||||
|
||||
// gl.uniform_3_f32(tex_shape.as_ref(), config.alt_range[1], config.lat_range[1], config.lon_range[1]);
|
||||
|
||||
gl.uniform_3_f32_slice(data_shape.as_ref(), &config.data_shape);
|
||||
gl.uniform_3_f32(dpi.as_ref(), config.alt_dpi, config.lat_dpi, config.lon_dpi);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +83,9 @@ impl GeoQuadMesh {
|
||||
[f32; 2],
|
||||
[f32; 2],
|
||||
[f32; 3],
|
||||
[f32; 3],
|
||||
ProbeDataType,
|
||||
f64,
|
||||
)> {
|
||||
if data.coord_type().is_none() {
|
||||
return Err(Error::InvalidDataType(format!("Invalid CoordType")));
|
||||
@ -91,16 +106,33 @@ impl GeoQuadMesh {
|
||||
let alt_dpi = (hgt[1] - hgt[0]);
|
||||
(Some([hgt_start, hgt_end]), alt_dpi)
|
||||
} else {
|
||||
(None, 0.0)
|
||||
(None, 1.0)
|
||||
};
|
||||
|
||||
let data_type = data.data_type();
|
||||
|
||||
let fill_value = data.info.fill_value;
|
||||
|
||||
let data_shape = data.data.shape();
|
||||
|
||||
let data_shape = if data_shape.len() == 3 {
|
||||
[
|
||||
data_shape[0] as f32,
|
||||
data_shape[1] as f32,
|
||||
data_shape[2] as f32,
|
||||
]
|
||||
} else {
|
||||
[1.0, data_shape[0] as f32, data_shape[1] as f32]
|
||||
};
|
||||
|
||||
Ok((
|
||||
hgt_range,
|
||||
[lat_start, lat_end],
|
||||
[lon_start, lon_end],
|
||||
[alt_dpi as f32, lat_dpi as f32, lon_dpi as f32],
|
||||
data_shape,
|
||||
data_type,
|
||||
fill_value,
|
||||
))
|
||||
}
|
||||
_ => Err(Error::InvalidDataType(format!("Invalid CoordType"))),
|
||||
@ -111,15 +143,21 @@ impl GeoQuadMesh {
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct GeoQuadMeshConfig {
|
||||
pub unvalid_value: f32,
|
||||
pub layer: usize,
|
||||
pub layer: f32,
|
||||
pub max_layer: usize,
|
||||
pub colors: Vec<[u8; 4]>,
|
||||
pub color_range: [f32; 2],
|
||||
pub lon_dpi: f32,
|
||||
pub lat_dpi: f32,
|
||||
pub alt_dpi: f32,
|
||||
pub data_shape: [f32; 3],
|
||||
pub lat_range: [f32; 2],
|
||||
pub lon_range: [f32; 2],
|
||||
pub alt_range: [f32; 2],
|
||||
pub scale: f32,
|
||||
pub offset: f32,
|
||||
pub min: f32,
|
||||
pub max: f32,
|
||||
}
|
||||
|
||||
impl Graphics for GeoQuadMesh {
|
||||
@ -137,7 +175,7 @@ impl Graphics for GeoQuadMesh {
|
||||
|
||||
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
||||
unsafe {
|
||||
gl.draw_arrays(glow::TRIANGLE_STRIP_ADJACENCY, 0, count);
|
||||
gl.draw_arrays(glow::TRIANGLE_STRIP, 0, count);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -276,8 +314,13 @@ impl AttaWithBuffer for GeoQuadMesh {
|
||||
(attach.textures.as_ref()).map(|t| t.native()),
|
||||
);
|
||||
|
||||
let _data = &data.data;
|
||||
let shape = _data.shape();
|
||||
let max_depth_size = gl.get_parameter_i32(glow::MAX_3D_TEXTURE_SIZE);
|
||||
info!("Max 3D Texture Size: {}", max_depth_size);
|
||||
|
||||
gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
|
||||
|
||||
let data = &data.data;
|
||||
let shape = data.shape();
|
||||
|
||||
let (depth, height, width) = if shape.len() == 2 {
|
||||
(1i32, shape[0] as i32, shape[1] as i32)
|
||||
@ -285,19 +328,39 @@ impl AttaWithBuffer for GeoQuadMesh {
|
||||
(shape[0] as i32, shape[1] as i32, shape[2] as i32)
|
||||
};
|
||||
|
||||
let pixels: &[u8] = cast_slice(_data.as_slice().unwrap());
|
||||
info!("Data Shape: {:?}", shape);
|
||||
|
||||
// let tex_width = width / 4 + 1;
|
||||
// let tex_height = height / 4 + 1;
|
||||
|
||||
let fill_value = config.unvalid_value;
|
||||
let min_value = config.min;
|
||||
let max_value = config.max;
|
||||
|
||||
let v = data.scale_offset_to_pixel(fill_value, min_value, max_value);
|
||||
|
||||
let pixel_num = (v.len() / 4 + 1) as f32;
|
||||
let edge_len = (pixel_num.powf(1.0 / 3.0) + 1.0) as usize;
|
||||
|
||||
let real_size = edge_len * edge_len * edge_len * 4;
|
||||
let data_size = v.len();
|
||||
let padding_size = real_size - data_size;
|
||||
|
||||
let mut pixels = vec![0u8; real_size as usize];
|
||||
&pixels[..data_size].copy_from_slice(cast_slice(v.as_slice().unwrap()));
|
||||
attach.texture_shape = Some([edge_len as f32; 3]);
|
||||
|
||||
gl.tex_image_3d(
|
||||
glow::TEXTURE_3D,
|
||||
0,
|
||||
glow::R8 as i32,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
glow::RGBA as i32,
|
||||
edge_len as i32,
|
||||
edge_len as i32,
|
||||
edge_len as i32,
|
||||
0,
|
||||
glow::RED,
|
||||
glow::RGBA,
|
||||
glow::UNSIGNED_BYTE,
|
||||
Some(pixels),
|
||||
Some(pixels.as_slice()),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -20,6 +20,32 @@ use crate::{
|
||||
|
||||
use glow::{HasContext, NativeBuffer, NativeTexture, NativeVertexArray};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! match_array_type {
|
||||
($array:ident, $just_do_it:expr) => {
|
||||
use radarg_core::ArrayData;
|
||||
match $array {
|
||||
ArrayData::U8(v) => $just_do_it(v),
|
||||
|
||||
ArrayData::U32(v) => $just_do_it(v),
|
||||
|
||||
ArrayData::U64(v) => $just_do_it(v),
|
||||
|
||||
ArrayData::I8(v) => $just_do_it(v),
|
||||
|
||||
ArrayData::I16(v) => $just_do_it(v),
|
||||
|
||||
ArrayData::I32(v) => $just_do_it(v),
|
||||
|
||||
ArrayData::I64(v) => $just_do_it(v),
|
||||
|
||||
ArrayData::F32(v) => $just_do_it(v),
|
||||
|
||||
ArrayData::F64(v) => $just_do_it(v),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub trait Graphics {
|
||||
const id: &'static str;
|
||||
type Config;
|
||||
|
||||
@ -208,7 +208,7 @@ impl AttaWithBuffer for PPI {
|
||||
for r_idx in 0..r_len {
|
||||
let azi = *azimuth.get(azi_idx).unwrap() as f32;
|
||||
let r = *range.get(r_idx).unwrap() as f32 / last_range;
|
||||
let data = &data.data;
|
||||
let data = &data.data.cast_to::<f32>();
|
||||
let dt = data.get([layer, azi_idx, r_idx]).unwrap();
|
||||
vertices.extend([r, azi, ele, *dt]);
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@ static MODULE_PACKAGE_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
#[derive(Debug)]
|
||||
pub enum SideBarInputMsg {
|
||||
Packages(Vec<(String, Rc<RefCell<ModulePackage>>)>),
|
||||
ClearPackages,
|
||||
SwitchTo(gtk::glib::GString),
|
||||
Refresh,
|
||||
None,
|
||||
@ -143,7 +144,7 @@ macro_rules! impl_module_package {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
// #[derive(Debug)]
|
||||
pub enum _ModulePackage {
|
||||
$(
|
||||
$b($t),
|
||||
@ -183,13 +184,19 @@ macro_rules! impl_module_package {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
// #[derive(Debug)]
|
||||
pub struct ModulePackage {
|
||||
id: usize,
|
||||
pub need_update: bool,
|
||||
modules: _ModulePackage,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ModulePackage {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "ModulePackage {{ id: {}, need_update: {} }}", self.id, self.need_update)
|
||||
}
|
||||
}
|
||||
|
||||
impl ModulePackage {
|
||||
|
||||
pub fn component_builder(&self) -> ComponentBuilders {
|
||||
|
||||
@ -16,11 +16,13 @@ use relm4::{
|
||||
gtk::{self, prelude::*},
|
||||
ComponentParts, SimpleComponent,
|
||||
};
|
||||
use toml::value;
|
||||
|
||||
use core::f32;
|
||||
use glow::HasContext;
|
||||
use std::{
|
||||
cell::{RefCell, RefMut},
|
||||
f32::consts::E,
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
};
|
||||
@ -120,7 +122,7 @@ impl<'b, 'a: 'b> GeoQuadMeshModule<'b, 'a> {
|
||||
config: &GeoQuadMeshModuleConfig,
|
||||
) -> Result<()> {
|
||||
self.geo_quad_mesh_program
|
||||
.bake(&self.gl, data, &config.to_quad_config(), attach)
|
||||
.bake(&self.gl, data, &mut config.to_quad_config(), attach)
|
||||
}
|
||||
|
||||
fn bind_line_pg(
|
||||
@ -140,6 +142,29 @@ impl<'b, 'a: 'b> GeoQuadMeshModule<'b, 'a> {
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn bind_attach_tex(&mut self, attach: &mut Attach) -> Result<()> {
|
||||
if let Some(tex) = attach.textures.as_ref() {
|
||||
unsafe {
|
||||
self.gl.active_texture(glow::TEXTURE1);
|
||||
self.gl.bind_texture(glow::TEXTURE_3D, Some(tex.native()));
|
||||
let loc = self
|
||||
.geo_quad_mesh_program
|
||||
.program()
|
||||
.get_uniform_location(&self.gl, "data_tex");
|
||||
self.gl.uniform_1_i32(loc.as_ref(), 1);
|
||||
|
||||
let tex_shape = self
|
||||
.geo_quad_mesh_program
|
||||
.program()
|
||||
.get_uniform_location(&self.gl, "tex_shape");
|
||||
|
||||
self.gl
|
||||
.uniform_3_f32_slice(tex_shape.as_ref(), &attach.texture_shape.unwrap());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
|
||||
@ -155,12 +180,6 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
|
||||
operation: &Operation<Self::Operation>,
|
||||
viewport: &ViewPort,
|
||||
) -> Result<()> {
|
||||
unsafe {
|
||||
let err = self.gl.get_error();
|
||||
if err != glow::NO_ERROR {
|
||||
panic!("Error: {}", err);
|
||||
}
|
||||
}
|
||||
// PPI Program
|
||||
let data = &cursor.data;
|
||||
let mut config = &mut cursor.ppi_config.borrow_mut();
|
||||
@ -169,25 +188,17 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
|
||||
// Deal with the operation
|
||||
operation.attach_with_program(&self.gl, self.geo_quad_mesh_program.program());
|
||||
let quad_attach = &mut cursor.quad_attach;
|
||||
unsafe {
|
||||
let err = self.gl.get_error();
|
||||
if err != glow::NO_ERROR {
|
||||
panic!("Error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the config
|
||||
self.geo_quad_mesh_program
|
||||
.set_config(&self.gl, &config.to_quad_config())?;
|
||||
unsafe {
|
||||
let err = self.gl.get_error();
|
||||
if err != glow::NO_ERROR {
|
||||
panic!("Error: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Quad Draw
|
||||
quad_attach.bind_self(self.geo_quad_mesh_program.program_ref());
|
||||
// Bind the texture
|
||||
self.bind_attach_tex(quad_attach)?;
|
||||
|
||||
// Draw the quad
|
||||
self.geo_quad_mesh_program
|
||||
.draw(&self.gl, quad_attach.len())?;
|
||||
|
||||
@ -207,11 +218,9 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
|
||||
let mut quad_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
|
||||
|
||||
// Get the data info
|
||||
let (hgt_range, lat_range, lon_range, dpi, t) =
|
||||
let (hgt_range, lat_range, lon_range, dpi, data_shape, t, fill_value) =
|
||||
self.geo_quad_mesh_program.data_info(&data)?;
|
||||
|
||||
println!("name: {}", data.info.value_name);
|
||||
|
||||
// Find the color map
|
||||
let cmap = setting.find(&t);
|
||||
|
||||
@ -232,6 +241,10 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
|
||||
let (vao, vbo, ebo, texs) = self.text_program.init(&self.gl);
|
||||
let mut tick_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
|
||||
|
||||
let value_range = cmap.value_range();
|
||||
let offset = -fill_value;
|
||||
let scale = value_range[1] / value_range[0];
|
||||
|
||||
let mut config = GeoQuadMeshModuleConfig::default();
|
||||
config.alt_dpi = dpi[0];
|
||||
config.lat_dpi = dpi[1];
|
||||
@ -242,9 +255,16 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
|
||||
config.hgt_range = hgt_range.unwrap_or_default();
|
||||
config.colors = cmap.color().unwrap();
|
||||
config.color_range = cmap.value_range();
|
||||
config.unvalid_value = fill_value as f32;
|
||||
config.scale = scale;
|
||||
config.offset = offset as f32;
|
||||
config.min = value_range[0] as f32;
|
||||
config.max = value_range[1] as f32;
|
||||
config.data_shape = data_shape;
|
||||
config.max_layer = data_shape[0] as usize;
|
||||
|
||||
// Bind the data
|
||||
self.bind_geo_quad_mesh_pg(&mut quad_attach, data, &config);
|
||||
self.bind_geo_quad_mesh_pg(&mut quad_attach, data, &config)?;
|
||||
|
||||
// self.bind_line_pg(&mut line_attach, &data, &config);
|
||||
// self.bind_tick(&mut tick_attach, &data.borrow(), &config);
|
||||
@ -272,7 +292,7 @@ impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
// #[derive(Debug)]
|
||||
pub struct GeoQuadMeshPackage {
|
||||
draw_helper: bool,
|
||||
ppi_config: Rc<RefCell<GeoQuadMeshModuleConfig>>,
|
||||
@ -308,7 +328,7 @@ pub struct GeoQuadMeshModuleConfig {
|
||||
pub line_color: [f32; 4],
|
||||
pub line_width: f32,
|
||||
pub line_antialias: f32,
|
||||
pub layer: usize,
|
||||
pub layer: f32,
|
||||
pub colors: Vec<[u8; 4]>,
|
||||
pub color_range: [f32; 2],
|
||||
pub is_three_d: bool,
|
||||
@ -334,6 +354,16 @@ pub struct GeoQuadMeshModuleConfig {
|
||||
pub alt_dpi: f32,
|
||||
#[do_not_track]
|
||||
pub lon_dpi: f32,
|
||||
#[do_not_track]
|
||||
pub scale: f32,
|
||||
#[do_not_track]
|
||||
pub offset: f32,
|
||||
#[do_not_track]
|
||||
pub min: f32,
|
||||
#[do_not_track]
|
||||
pub max: f32,
|
||||
#[do_not_track]
|
||||
pub data_shape: [f32; 3],
|
||||
}
|
||||
|
||||
impl Default for GeoQuadMeshModuleConfig {
|
||||
@ -343,7 +373,7 @@ impl Default for GeoQuadMeshModuleConfig {
|
||||
line_color: [1.0, 1.0, 1.0, 1.0],
|
||||
line_width: 1.5,
|
||||
line_antialias: 0.5,
|
||||
layer: 0,
|
||||
layer: 0.0,
|
||||
colors: vec![],
|
||||
color_range: [0.0, 0.0],
|
||||
is_three_d: true,
|
||||
@ -358,6 +388,11 @@ impl Default for GeoQuadMeshModuleConfig {
|
||||
lat_range: [0.0, 0.0],
|
||||
lon_range: [0.0, 0.0],
|
||||
hgt_range: [0.0, 0.0],
|
||||
scale: 1.0,
|
||||
offset: 0.0,
|
||||
min: 0.0,
|
||||
max: 0.0,
|
||||
data_shape: [0.0, 0.0, 0.0],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -375,6 +410,12 @@ impl GeoQuadMeshModuleConfig {
|
||||
lat_range: self.lat_range,
|
||||
lon_range: self.lon_range,
|
||||
alt_range: self.hgt_range,
|
||||
scale: self.scale,
|
||||
offset: self.offset,
|
||||
min: self.min,
|
||||
max: self.max,
|
||||
data_shape: self.data_shape,
|
||||
max_layer: self.max_layer,
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,6 +467,27 @@ impl SimpleComponent for GeoQuadMeshModuleConfigComponent {
|
||||
}
|
||||
},
|
||||
|
||||
adw::SpinRow {
|
||||
set_title: "Layer",
|
||||
set_digits: 0,
|
||||
set_numeric: true,
|
||||
set_snap_to_ticks: true,
|
||||
#[wrap(Some)]
|
||||
set_adjustment=>k::Adjustment::new(
|
||||
init_config.layer as f64,
|
||||
init_config.hgt_range[0] as f64,
|
||||
init_config.hgt_range[1] as f64,
|
||||
init_config.alt_dpi as f64,
|
||||
1.0,
|
||||
1.0,
|
||||
),
|
||||
connect_value_notify[sender, config_ref] => move |this| {
|
||||
let num = this.value() as f32;
|
||||
config_ref.borrow_mut().set_layer(num);
|
||||
sender.output(OutputMsg::Refresh);
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ pub(crate) struct Attach {
|
||||
pub vbo: RcGlRcBuffer,
|
||||
pub ebo: Option<RcGlRcBuffer>,
|
||||
pub textures: Option<RcGlRcResource<NativeTexture>>,
|
||||
pub texture_shape: Option<[f32; 3]>,
|
||||
pub len: i32,
|
||||
}
|
||||
|
||||
@ -58,6 +59,7 @@ impl Attach {
|
||||
vbo,
|
||||
ebo,
|
||||
textures,
|
||||
texture_shape: None,
|
||||
len: len.unwrap_or(0),
|
||||
}
|
||||
}
|
||||
@ -68,15 +70,6 @@ impl Attach {
|
||||
if let Some(ebo) = self.ebo.as_ref() {
|
||||
ebo.bind(glow::ELEMENT_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
if let Some(tex) = self.textures.as_ref() {
|
||||
unsafe {
|
||||
self.gl.active_texture(glow::TEXTURE0);
|
||||
self.gl.bind_texture(glow::TEXTURE_3D, Some(tex.native()));
|
||||
let loc = program.get_uniform_location(&self.gl, "_texture");
|
||||
self.gl.uniform_1_i32(loc.as_ref(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn unbind_self(&self) {
|
||||
|
||||
@ -434,7 +434,7 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
// #[derive(Debug)]
|
||||
pub struct PPIPackage {
|
||||
draw_helper: bool,
|
||||
ppi_config: Rc<RefCell<PPIModuleConfig>>,
|
||||
|
||||
@ -39,7 +39,7 @@ impl ColorMap {
|
||||
float v = clamp((value - vmin), vmin, vmax) / (vmax - vmin);
|
||||
float idx = find_idx(v);
|
||||
vec4 result = texture(colormap, idx);
|
||||
return result;
|
||||
return vec4(result.rgb, 1.0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ use glsl_quasiquote::glsl;
|
||||
use super::proj::Mercator;
|
||||
|
||||
pub struct GeoQuadMeshVertex(pub ShaderStage);
|
||||
pub struct GeoQuadMeshGeom(pub ShaderStage);
|
||||
// pub struct GeoQuadMeshGeom(pub ShaderStage);
|
||||
pub struct GeoQuadMeshFragment(pub ShaderStage);
|
||||
|
||||
impl GeoQuadMeshVertex {
|
||||
@ -46,9 +46,15 @@ impl GeoQuadMeshFragment {
|
||||
let raw = glsl! {
|
||||
// lon_s,lon_e, lat_s, lat_e
|
||||
uniform vec4 tex_conf;
|
||||
|
||||
// lon_reso, lat_reso, alt_reso
|
||||
// hgt, lat, lon
|
||||
uniform vec3 tex_shape;
|
||||
// offset, scale, min, max
|
||||
uniform vec4 data_info;
|
||||
// data shape
|
||||
uniform vec3 data_shape;
|
||||
|
||||
// hgt, lat, lon
|
||||
uniform vec3 dpi;
|
||||
|
||||
// Current layer
|
||||
uniform float layer;
|
||||
@ -57,25 +63,63 @@ impl GeoQuadMeshFragment {
|
||||
in vec2 projected_meter;
|
||||
|
||||
// data array
|
||||
uniform sampler3D _texture;
|
||||
uniform sampler3D data_tex;
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 lon_lat = mercatorInverse(projected_meter);
|
||||
|
||||
vec3 tex_coord = vec3(lon_lat.x / tex_conf.z, lon_lat.y / tex_conf.w, layer / tex_conf.x);
|
||||
float x = round((lon_lat.x - tex_conf.x) / dpi.z);
|
||||
float y = round((lon_lat.y - tex_conf.z) / dpi.y);
|
||||
float z = floor(layer / dpi.x);
|
||||
|
||||
float value = texture(_texture, tex_coord).r;
|
||||
uint raw_loc = uint(z * (data_shape.y * data_shape.z) + y * data_shape.z + x);
|
||||
|
||||
uint loc = raw_loc / 4u;
|
||||
uint channel = raw_loc % 4u;
|
||||
|
||||
uint tex_depth = uint(tex_shape.x);
|
||||
uint tex_height = uint(tex_shape.y);
|
||||
uint tex_width = uint(tex_shape.z);
|
||||
|
||||
float tz = float(loc / (tex_width * tex_height));
|
||||
float ty = float((loc % (tex_height * tex_width) / tex_width));
|
||||
float tx = float(loc % tex_width);
|
||||
|
||||
vec3 tex_coord = vec3(tx / tex_shape.z, ty / tex_shape.y, tz / tex_shape.x);
|
||||
|
||||
vec4 _value = texture(data_tex, tex_coord);
|
||||
|
||||
float value = 0.0;
|
||||
|
||||
switch (channel) {
|
||||
case 0:
|
||||
value = _value.r;
|
||||
break;
|
||||
case 1:
|
||||
value = _value.g;
|
||||
break;
|
||||
case 2:
|
||||
value = _value.b;
|
||||
break;
|
||||
case 3:
|
||||
value = _value.a;
|
||||
break;
|
||||
}
|
||||
|
||||
float min = data_info.z;
|
||||
float max = data_info.w;
|
||||
|
||||
if (abs(value - 0.0) < 0.0001) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// Real value
|
||||
value = value * 255.0 / 254.0 * (max - min);
|
||||
|
||||
vec4 color = linear_colormap(value);
|
||||
|
||||
fragColor = vec4(1.0,1.0,1.0,1.0);
|
||||
|
||||
// if (color.a < 0.1) {
|
||||
// discard;
|
||||
// } else {
|
||||
// fragColor = color;
|
||||
// }
|
||||
fragColor = color;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@ -106,7 +106,7 @@ impl DataLoaderPlugin for ETWSLoader {
|
||||
let data_type = data_type!(
|
||||
value_key,
|
||||
{ "ET" => ET },
|
||||
{ "DBZ" | "CR" | "FR" | "R" => DBZ},
|
||||
{ "DBZ" | "CR" | "FR" | "R" | "CR0" | "CR1" | "CR2" => DBZ},
|
||||
{ "VIL" => VIL},
|
||||
{ "EB" => EB},
|
||||
{ "V" => V},
|
||||
@ -165,7 +165,7 @@ impl DataLoaderPlugin for ETWSLoader {
|
||||
let data_type = data_type!(
|
||||
k,
|
||||
{ "ET" => ET },
|
||||
{ "DBZ" | "CR" | "FR" | "R" => DBZ},
|
||||
{ "DBZ" | "CR" | "FR" | "R" | "CR0" | "CR1" | "CR2" => DBZ},
|
||||
{ "VIL" => VIL},
|
||||
{ "EB" => EB},
|
||||
{ "V" | "VEL" => V},
|
||||
|
||||
@ -71,6 +71,7 @@ pub enum AppMsg {
|
||||
CloseRequest,
|
||||
Close,
|
||||
OpenFileDialog,
|
||||
Packages { clear: bool },
|
||||
}
|
||||
#[tracker::track]
|
||||
pub struct AppModel {
|
||||
@ -221,6 +222,13 @@ impl Component for AppModel {
|
||||
.forward(sender.input_sender(), |msg| match msg {
|
||||
SideBarOutputMsg::Dialog(widget) => AppMsg::OpenDialog { widget },
|
||||
SideBarOutputMsg::QueueDraw => AppMsg::Refresh,
|
||||
SideBarOutputMsg::Packages { clear } => {
|
||||
if clear {
|
||||
AppMsg::Packages { clear: true }
|
||||
} else {
|
||||
AppMsg::Refresh
|
||||
}
|
||||
}
|
||||
_ => AppMsg::Close,
|
||||
});
|
||||
|
||||
@ -404,7 +412,8 @@ impl Component for AppModel {
|
||||
let mut datapool = self.file_pool.borrow_mut();
|
||||
match datapool.get_or_load(path) {
|
||||
Ok(data) => {
|
||||
info!("data: {}", data);
|
||||
info!("data: {:?}", data);
|
||||
_sender.input(AppMsg::Packages { clear: true });
|
||||
_sender.input(AppMsg::FileIO {
|
||||
typ: FileIOType::Open(data),
|
||||
});
|
||||
@ -423,6 +432,10 @@ impl Component for AppModel {
|
||||
} => self.render.emit(MonitorInputMsg::PushData(data)),
|
||||
|
||||
AppMsg::Refresh => self.render.emit(MonitorInputMsg::QueueDraw),
|
||||
|
||||
AppMsg::Packages { clear } => {
|
||||
self.render.emit(MonitorInputMsg::Packages { clear: true });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
self.update_view(widgets, _sender);
|
||||
|
||||
@ -10,6 +10,7 @@ pub enum MonitorInputMsg {
|
||||
Prepare(Vec<Arc<Data>>),
|
||||
KeyPress(u32),
|
||||
KeyRelease(u32),
|
||||
Packages { clear: bool },
|
||||
QueueDraw,
|
||||
None,
|
||||
}
|
||||
@ -27,6 +28,10 @@ impl Debug for MonitorInputMsg {
|
||||
MonitorInputMsg::KeyPress(key) => write!(f, "MonitorInputMsg::Key({:?})", key),
|
||||
MonitorInputMsg::KeyRelease(key) => write!(f, "MonitorInputMsg::KeyRelease({:?})", key),
|
||||
MonitorInputMsg::PushData(data) => write!(f, "MonitorInputMsg::PushData({:?})", data),
|
||||
|
||||
&MonitorInputMsg::Packages { clear } => {
|
||||
write!(f, "MonitorInputMsg::Packages {{ clear: {} }}", clear)
|
||||
}
|
||||
MonitorInputMsg::None => write!(f, "MonitorInputMsg::None"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,6 +236,12 @@ impl Component for MonitorModel {
|
||||
MonitorInputMsg::KeyRelease(key) => {
|
||||
widgets.renderer.set_key_released(key);
|
||||
}
|
||||
|
||||
MonitorInputMsg::Packages { clear } => {
|
||||
if clear {
|
||||
self.update_module_packages(|p| p.clear());
|
||||
}
|
||||
}
|
||||
MonitorInputMsg::None => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ pub struct SideBarModel {
|
||||
#[derive(Debug)]
|
||||
pub enum SideBarOutputMsg {
|
||||
Dialog(Widget),
|
||||
Packages { clear: bool },
|
||||
QueueDraw,
|
||||
}
|
||||
|
||||
@ -76,6 +77,13 @@ impl Component for SideBarModel {
|
||||
set_transition_type:gtk::StackTransitionType::SlideLeftRight,
|
||||
set_transition_duration:200,
|
||||
set_hexpand:true,
|
||||
},
|
||||
|
||||
gtk::Button {
|
||||
set_label:"Clear",
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(SideBarInputMsg::ClearPackages);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -133,6 +141,14 @@ impl Component for SideBarModel {
|
||||
sender.output(SideBarOutputMsg::QueueDraw).unwrap();
|
||||
}
|
||||
|
||||
SideBarInputMsg::ClearPackages => {
|
||||
widgets.stack.remove_all();
|
||||
self.components.clear();
|
||||
widgets.dropdown.set_selected(gtk::INVALID_LIST_POSITION);
|
||||
widgets.dropdown.set_model(None::<>k::StringList>);
|
||||
sender.output(SideBarOutputMsg::Packages { clear: true });
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,15 +44,15 @@ impl<T: Display> Deref for Value<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Value<Data> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for data in self.0.iter() {
|
||||
writeln!(f, "{:?}", data)?;
|
||||
}
|
||||
// impl Display for Value<Data> {
|
||||
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
// for data in self.0.iter() {
|
||||
// writeln!(f, "{:?}", data)?;
|
||||
// }
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
// Ok(())
|
||||
// }
|
||||
// }
|
||||
|
||||
pub struct DataPool {
|
||||
plugin_manager: &'static PluginManager,
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use num_traits::FromPrimitive;
|
||||
use std::{
|
||||
fmt::Display,
|
||||
hash::Hash,
|
||||
@ -14,13 +15,23 @@ use radarg_plugin_interface::{
|
||||
|
||||
static DATA_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct Data {
|
||||
pub id: usize,
|
||||
pub description: String,
|
||||
_data: _Data,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Data {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Data {{ id: {}, description: {}",
|
||||
self.id, self.description
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Data {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
@ -41,7 +52,7 @@ impl Display for Data {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone)]
|
||||
pub enum _Data {
|
||||
RadarGridData(Arc<RadarGridData>),
|
||||
JsonData,
|
||||
@ -60,14 +71,14 @@ impl Display for _Data {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct RadarGridData {
|
||||
pub data: ArrayD<f32>,
|
||||
pub data: ArrayData,
|
||||
pub info: GridDataInfo,
|
||||
}
|
||||
|
||||
impl RadarGridData {
|
||||
pub fn get_data(&self) -> &ArrayD<f32> {
|
||||
pub fn get_data(&self) -> &ArrayData {
|
||||
&self.data
|
||||
}
|
||||
|
||||
@ -195,7 +206,67 @@ pub enum ProbeDataType {
|
||||
}
|
||||
|
||||
macro_rules! raw2new {
|
||||
($({$raw_bc:tt}),+, ($({$raw_rdt:tt}),+)) => {
|
||||
($({$raw_bc:tt | $typ:ty | $from:ident}),+, ($({$raw_rdt:tt}),+)) => {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ArrayData {
|
||||
$(
|
||||
$raw_bc(ArrayD<$typ>),
|
||||
)+
|
||||
}
|
||||
|
||||
impl ArrayData {
|
||||
pub fn shape(&self) -> &[usize] {
|
||||
match self {
|
||||
$(
|
||||
ArrayData::$raw_bc(v) => v.shape(),
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cast_to<T: FromPrimitive>(&self) -> ArrayD<T> {
|
||||
match self {
|
||||
$(
|
||||
ArrayData::$raw_bc(v) => v.map(|v| T::$from(*v).unwrap()),
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scale_offset(&self, scale: f64, offset: f64) -> ArrayD<f32>{
|
||||
match self {
|
||||
$(
|
||||
ArrayData::$raw_bc(v) => v.mapv(|v| v as f32 * scale as f32 + offset as f32),
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scale_offset_to_pixel(&self, fill_value:f32, min:f32, max:f32) -> ArrayD<u8>{
|
||||
match self {
|
||||
$(
|
||||
ArrayData::$raw_bc(v) => v.mapv(|v| {
|
||||
if (v as f32 - fill_value).abs() < 1e-6 {
|
||||
0
|
||||
} else {
|
||||
let v = (v as f32 - min) / (max - min) * 254.0;
|
||||
v as u8 + 1
|
||||
}
|
||||
}),
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$(
|
||||
pub fn $raw_bc(&self) -> &ArrayD<$typ> {
|
||||
match self {
|
||||
ArrayData::$raw_bc(v) => v,
|
||||
_ => panic!("Unsupported data type"),
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
||||
}
|
||||
|
||||
impl From<RawRadarGridData> for RadarGridData {
|
||||
fn from(raw: RawRadarGridData) -> Self {
|
||||
let RawRadarGridData { data, info } = raw;
|
||||
@ -205,8 +276,7 @@ macro_rules! raw2new {
|
||||
let data = match data {
|
||||
$(
|
||||
$raw_bc(v) => {
|
||||
let data = v.into_iter().map(|x| x as f32).collect();
|
||||
ArrayD::from_shape_vec(shape.clone(), data).unwrap()
|
||||
ArrayData::$raw_bc(ArrayD::from_shape_vec(shape.clone(), v.to_vec()).unwrap())
|
||||
}
|
||||
)+
|
||||
_ => panic!("Unsupported data type"),
|
||||
@ -243,16 +313,15 @@ macro_rules! raw2new {
|
||||
}
|
||||
|
||||
raw2new!(
|
||||
{ F32 },
|
||||
{ F64 },
|
||||
{ I32 },
|
||||
{ I16 },
|
||||
{ F32 },
|
||||
{ U64 },
|
||||
{ U32 },
|
||||
{ I8 },
|
||||
{ U8 },
|
||||
{ I64 },
|
||||
{ F32 | f32 | from_f32 },
|
||||
{ F64 | f64 | from_f64 },
|
||||
{ I32 | i32 | from_i32 },
|
||||
{ I16 | i16 | from_i16 },
|
||||
{ U64 | u64 | from_u64 },
|
||||
{ U32 | u32 | from_u32 },
|
||||
{ I8 | i8 | from_i8 },
|
||||
{ U8 | u8 | from_u8 },
|
||||
{ I64 | i64 | from_i64 },
|
||||
(
|
||||
{ R },
|
||||
{ V },
|
||||
@ -347,10 +416,5 @@ mod test {
|
||||
|
||||
use super::Data;
|
||||
|
||||
fn test() {
|
||||
let radar_data = RadarGridData {
|
||||
data: ndarray::ArrayD::from_shape_vec(ndarray::IxDyn(&[1, 1]), vec![1.0]).unwrap(),
|
||||
info: super::GridDataInfo::default(),
|
||||
};
|
||||
}
|
||||
fn test() {}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user