diff --git a/src/js/Aladin.js b/src/js/Aladin.js index de78bf5b..e33cfbdf 100644 --- a/src/js/Aladin.js +++ b/src/js/Aladin.js @@ -568,7 +568,8 @@ export let Aladin = (function () { Aladin.prototype.setProjection = function (projectionName) { console.log('setProj', projectionName); this.webglAPI.setProjection(projectionName); - + this.view.fov_limit = this.webglAPI.getMaxFieldOfView() * 180 / Math.PI; + console.log("FOV LIMITE", this.view.fov_limit); /* if (!projectionName) { return; @@ -1096,7 +1097,7 @@ export let Aladin = (function () { layerBox.append('
' + '
Projection
' + - '
'); + '
'); $('#projectionChoice').change(function () { aladin.setProjection($(this).val()); diff --git a/src/js/View.js b/src/js/View.js index a2aa321c..398bcbb2 100644 --- a/src/js/View.js +++ b/src/js/View.js @@ -115,6 +115,7 @@ export let View = (function() { this.mode = View.PAN; this.minFOV = this.maxFOV = null; // by default, no restriction + this.fov_limit = 180.0; this.healpixGrid = new HealpixGrid(this.imageCanvas); if (cooFrame) { @@ -402,7 +403,8 @@ export let View = (function() { // if zoom factor < 1, we view 180° var fov; if (view.zoomFactor<1) { - fov = 180; + console.log(view.fov_limit) + fov = view.fov_limit; //fov = 360; } else { @@ -418,7 +420,7 @@ export let View = (function() { fov = new Coo(lonlat1.ra, lonlat1.dec).distance(new Coo(lonlat2.ra, lonlat2.dec)); } - fov = Math.min(360, fov); + fov = Math.min(view.fov_limit, fov); return fov; } @@ -730,6 +732,9 @@ export let View = (function() { //pos2 = view.projection.unproject(xy2.x, xy2.y); pos1 = webglAPI.screenToWorld(view.dragx, view.dragy); pos2 = webglAPI.screenToWorld(e.originalEvent.targetTouches[0].clientX, e.originalEvent.targetTouches[0].clientY); + if (pos2 == undefined) { + return; + } } else { /* @@ -746,6 +751,10 @@ export let View = (function() { pos1 = webglAPI.screenToWorld(view.dragx, view.dragy); pos2 = webglAPI.screenToWorld(xymouse.x, xymouse.y); + + if (pos2 == undefined) { + return; + } } // TODO : faut il faire ce test ?? @@ -1556,18 +1565,26 @@ export let View = (function() { View.prototype.computeZoomFactor = function(level) { if (level>0) { - return AladinUtils.getZoomFactorForAngle(180/Math.pow(1.15, level), this.projectionMethod); + return AladinUtils.getZoomFactorForAngle(this.fov_limit/Math.pow(1.15, level), this.projectionMethod); } else { return 1 + 0.1*level; } }; + /*View.prototype.computeZoomLevelFromFOV = function() { + if (level>0) { + return AladinUtils.getZoomFactorForAngle(180/Math.pow(1.15, level), this.projectionMethod); + } + else { + return 1 + 0.1*level; + } + };*/ View.prototype.setZoom = function(fovDegrees) { - if (fovDegrees<0 || (fovDegrees>180 && ! this.aladin.options.allowFullZoomout)) { + if (fovDegrees<0 || (fovDegrees>this.fov_limit && ! this.aladin.options.allowFullZoomout)) { return; } - var zoomLevel = Math.log(180/fovDegrees)/Math.log(1.15); + var zoomLevel = Math.log(this.fov_limit/fovDegrees)/Math.log(1.15); this.setZoomLevel(zoomLevel); }; @@ -1587,29 +1604,30 @@ export let View = (function() { zoom["action"] = "zoom"; }*/ - if (this.minFOV || this.maxFOV) { + /*if (this.minFOV || this.maxFOV) { var newFov = doComputeFov(this, this.computeZoomFactor(Math.max(-2, level))); if (this.maxFOV && newFov>this.maxFOV || this.minFOV && newFov= 1.0) { this.aladin.webglAPI.setFieldOfView(this.fov); } else { - console.log("FOV, ", this.fov / this.zoomFactor); // zoom factor diff --git a/src/render/src/buffer/hips_config.rs b/src/render/src/buffer/hips_config.rs index 00b552b5..9af14712 100644 --- a/src/render/src/buffer/hips_config.rs +++ b/src/render/src/buffer/hips_config.rs @@ -153,14 +153,18 @@ impl HiPSConfig { tex_storing_integers = 1; Ok(FormatImageType::FITS(FITS::new(WebGl2RenderingContext::R16I as i32))) }, - /*32 => { + 32 => { tex_storing_integers = 1; Ok(FormatImageType::FITS(FITS::new(WebGl2RenderingContext::R32I as i32))) - },*/ + }, -32 => { tex_storing_integers = 0; Ok(FormatImageType::FITS(FITS::new(WebGl2RenderingContext::R32F as i32))) }, + -64 => { + tex_storing_integers = 0; + Ok(FormatImageType::FITS(FITS::new(WebGl2RenderingContext::R32F as i32))) + }, _ => { Err(format!("Fits tiles exists but the BITPIX is not correct in the property file").into()) } diff --git a/src/render/src/buffer/image.rs b/src/render/src/buffer/image.rs index f8c9c04d..7410899e 100644 --- a/src/render/src/buffer/image.rs +++ b/src/render/src/buffer/image.rs @@ -643,7 +643,6 @@ impl ImageRequest for FITSImageRequest { //crate::log(&format!("bytes {:?}", bytes)); if let Ok(Fits { data, header }) = Fits::from_bytes_slice(bytes) { let num_channels = format.get_num_channels() as i32; - //crate::log(&format!("data {:?}", data)); let image = match data { DataType::U8(data) => { @@ -659,7 +658,8 @@ impl ImageRequest for FITSImageRequest { TileArrayBufferImage::F32(TileArrayBuffer::::new(&data.0, tile_width, num_channels)) }, DataType::F64(data) => { - TileArrayBufferImage::F64(TileArrayBuffer::::new(&data.0, tile_width, num_channels)) + let data = data.0.into_iter().map(|v| v as f32).collect::>(); + TileArrayBufferImage::F32(TileArrayBuffer::::new(&data, tile_width, num_channels)) }, _ => unimplemented!() }; diff --git a/src/render/src/buffer/image_survey_buffer_textures.rs b/src/render/src/buffer/image_survey_buffer_textures.rs index 61289785..e8cdc827 100644 --- a/src/render/src/buffer/image_survey_buffer_textures.rs +++ b/src/render/src/buffer/image_survey_buffer_textures.rs @@ -218,7 +218,7 @@ impl ImageSurveyTextures { // This method pushes a new downloaded tile into the buffer // It must be ensured that the tile is not already contained into the buffer - pub fn push(&mut self, tile: Tile, image: I, time_request: Time) { + pub fn push(&mut self, tile: Tile, image: I, time_request: Time, missing: bool) { let tile_cell = tile.cell; // Assert here to prevent pushing doublons if self.contains_tile(&tile_cell) { @@ -283,7 +283,8 @@ impl ImageSurveyTextures { if let Some(texture) = self.textures.get_mut(&texture_cell) { texture.append( &tile_cell, // The tile cell - &self.config + &self.config, + missing ); // Compute the cutoff of the received tile //let cutoff = image.get_cutoff_values(); diff --git a/src/render/src/buffer/texture.rs b/src/render/src/buffer/texture.rs index 815ac538..bcc7cbbe 100644 --- a/src/render/src/buffer/texture.rs +++ b/src/render/src/buffer/texture.rs @@ -34,6 +34,7 @@ pub struct Texture { // Flag telling whether the texture is available // for drawing is_available: bool, + missing: bool, } use crate::buffer::HiPSConfig; @@ -48,6 +49,7 @@ impl Texture { let texture_cell = *texture_cell; let uniq = texture_cell.uniq(); let is_available = false; + let missing = true; let num_tiles_written = 0; Texture { texture_cell, @@ -59,6 +61,7 @@ impl Texture { full, is_available, num_tiles_written, + missing } } @@ -67,12 +70,15 @@ impl Texture { // Return true if the tile is newly added pub fn append(&mut self, cell: &HEALPixCell, - config: &HiPSConfig + config: &HiPSConfig, + missing: bool ) { let texture_cell = cell.get_texture_cell(config); assert!(texture_cell == self.texture_cell); assert!(!self.full); + self.missing &= missing; + // cell has the good ancestor for this texture let new_tile = self.tiles.insert(*cell); // Ensures the tile was not already present in the buffer @@ -163,6 +169,7 @@ impl Texture { self.time_request = time_request; self.tiles.clear(); self.is_available = false; + self.missing = true; self.num_tiles_written = 0; } @@ -214,6 +221,7 @@ impl<'a> SendUniforms for TextureUniforms<'a> { fn attach_uniforms<'b>(&self, shader: &'b ShaderBound<'b>) -> &'b ShaderBound<'b> { shader.attach_uniform(&format!("{}{}", self.name, "uniq"), &self.texture.uniq) .attach_uniform(&format!("{}{}", self.name, "texture_idx"), &self.texture.idx) + .attach_uniform(&format!("{}{}", self.name, "empty"), &(self.texture.missing as i32)) .attach_uniform(&format!("{}{}", self.name, "start_time"), &self.texture.start_time()); shader diff --git a/src/render/src/lib.rs b/src/render/src/lib.rs index 28b1a386..995df62b 100644 --- a/src/render/src/lib.rs +++ b/src/render/src/lib.rs @@ -552,7 +552,9 @@ impl App { self.look_for_new_tiles(); self.request_redraw = true; } - + fn get_max_fov(&self) -> f32 { + P::aperture_start().0 + } fn set_longitude_reversed(&mut self, reversed: bool) { /*if reversed { self.gl.cull_face(WebGl2RenderingContext::BACK); @@ -659,9 +661,12 @@ impl App { Ok(screen_pos) } - pub fn screen_to_world(&self, pos: &Vector2) -> Result, String> { - let model_pos = P::screen_to_model_space(pos, &self.camera).ok_or(format!("{:?} is out of projection", pos))?; - Ok(model_pos.lonlat()) + pub fn screen_to_world(&self, pos: &Vector2) -> Option> { + if let Some(model_pos) = P::screen_to_model_space(pos, &self.camera) { + Some(model_pos.lonlat()) + } else { + None + } } pub fn set_center(&mut self, lonlat: &LonLatT) { @@ -846,7 +851,19 @@ impl ProjectionType { } } - fn screen_to_world(&self, app: &App, pos: &Vector2) -> Result, String> { + + fn get_max_fov(&self, app: &App) -> f32 { + match self { + ProjectionType::Aitoff => app.get_max_fov::(), + ProjectionType::MollWeide => app.get_max_fov::(), + ProjectionType::Ortho => app.get_max_fov::(), + ProjectionType::Arc => app.get_max_fov::(), + ProjectionType::Gnomonic => app.get_max_fov::(), + ProjectionType::Mercator => app.get_max_fov::(), + } + } + + fn screen_to_world(&self, app: &App, pos: &Vector2) -> Option> { match self { ProjectionType::Aitoff => app.screen_to_world::(pos), ProjectionType::MollWeide => app.screen_to_world::(pos), @@ -1375,13 +1392,15 @@ impl WebClient { } #[wasm_bindgen(js_name = screenToWorld)] - pub fn screen_to_world(&self, pos_x: f32, pos_y: f32) -> Result, JsValue> { - let lonlat = self.projection.screen_to_world(&self.app, &Vector2::new(pos_x, pos_y))?; + pub fn screen_to_world(&self, pos_x: f32, pos_y: f32) -> Option> { + if let Some(lonlat) = self.projection.screen_to_world(&self.app, &Vector2::new(pos_x, pos_y)) { + let lon_deg: ArcDeg = lonlat.lon().into(); + let lat_deg: ArcDeg = lonlat.lat().into(); - let lon_deg: ArcDeg = lonlat.lon().into(); - let lat_deg: ArcDeg = lonlat.lat().into(); - - Ok(Box::new([lon_deg.0, lat_deg.0])) + Some(Box::new([lon_deg.0, lat_deg.0])) + } else { + None + } } #[wasm_bindgen(js_name = getFieldOfView)] @@ -1410,12 +1429,11 @@ impl WebClient { Ok(()) } - - #[wasm_bindgen(js_name = setClipZoomFactor)] - pub fn set_clip_zoom_factor(&mut self, clip_zoom_factor: f32) -> Result<(), JsValue> { - Ok(()) - } + #[wasm_bindgen(js_name = getMaxFieldOfView)] + pub fn get_max_fov(&mut self) -> f32 { + self.projection.get_max_fov(&mut self.app) + } /// Set directly the center position #[wasm_bindgen(js_name = getCenter)] pub fn get_center(&self) -> Result, JsValue> { diff --git a/src/render/src/renderable/image_survey.rs b/src/render/src/renderable/image_survey.rs index 017e7768..bb7c331f 100644 --- a/src/render/src/renderable/image_survey.rs +++ b/src/render/src/renderable/image_survey.rs @@ -1312,11 +1312,12 @@ impl ImageSurveys { let textures = survey.get_textures_mut(); match result { TileResolved::Missing { time_req } => { - + let missing = true; let default_image = textures.config().get_black_tile(); - textures.push::>(tile, default_image, time_req); + textures.push::>(tile, default_image, time_req, missing); }, TileResolved::Found { image, time_req } => { + let missing = false; match image { RetrievedImageType::FITSImage { image, metadata } => { // Update the metadata found in the header of the @@ -1328,13 +1329,13 @@ impl ImageSurveys { textures.config.scale = metadata.bscale; textures.config.offset = metadata.bzero; // Update the blank textures - textures.config.set_black_tile_value(metadata.bscale*blank + metadata.bzero); + textures.config.set_black_tile_value(blank); - textures.push::(tile, image, time_req); + textures.push::(tile, image, time_req, missing); }, RetrievedImageType::CompressedImage { image } => { - textures.push::(tile, image, time_req); + textures.push::(tile, image, time_req, missing); } } } diff --git a/src/render/src/shaders/hips/color_i.glsl b/src/render/src/shaders/hips/color_i.glsl index 9ecde68a..a33dd7d9 100644 --- a/src/render/src/shaders/hips/color_i.glsl +++ b/src/render/src/shaders/hips/color_i.glsl @@ -46,10 +46,6 @@ float get_grayscale_from_texture(vec3 UV) { float x = get_pixels(uv); - /*if (x == blank) { - return transparent; - }*/ - float alpha = x * scale + offset; float h = transfer_func(H, alpha, min_value, max_value); diff --git a/src/render/src/shaders/hips/raytracer/color.frag b/src/render/src/shaders/hips/raytracer/color.frag index 3d977332..a8d7de92 100644 --- a/src/render/src/shaders/hips/raytracer/color.frag +++ b/src/render/src/shaders/hips/raytracer/color.frag @@ -16,6 +16,7 @@ struct Tile { int uniq; // Healpix cell int texture_idx; // Index in the texture buffer float start_time; // Absolute time that the load has been done in ms + int missing; }; uniform int current_depth; @@ -65,16 +66,20 @@ TileColor get_tile_color(vec3 pos, int depth) { if (uniq == textures_tiles[i].uniq) { Tile tile = textures_tiles[i]; - int idx_texture = tile.texture_idx >> 6; - int off = tile.texture_idx % 64; - float idx_row = float(off >> 3); // in [0; 7] - float idx_col = float(off % 8); // in [0; 7] + if (tile.empty == 1) { + return TileColor(tile, vec3(0.0), true); + } else { + int idx_texture = tile.texture_idx >> 6; + int off = tile.texture_idx % 64; + float idx_row = float(off >> 3); // in [0; 7] + float idx_col = float(off % 8); // in [0; 7] - vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; - vec3 UV = vec3(offset, float(idx_texture)); + vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; + vec3 UV = vec3(offset, float(idx_texture)); - vec3 color = get_color_from_texture(UV).rgb; - return TileColor(tile, color, true); + vec3 color = get_color_from_texture(UV).rgb; + return TileColor(tile, color, true); + } } else if (uniq < textures_tiles[i].uniq) { // go to left b = i - 1; diff --git a/src/render/src/shaders/hips/raytracer/grayscale_to_color.frag b/src/render/src/shaders/hips/raytracer/grayscale_to_color.frag index 05dacedb..98f01105 100644 --- a/src/render/src/shaders/hips/raytracer/grayscale_to_color.frag +++ b/src/render/src/shaders/hips/raytracer/grayscale_to_color.frag @@ -15,6 +15,7 @@ struct Tile { int uniq; // Healpix cell int texture_idx; // Index in the texture buffer float start_time; // Absolute time that the load has been done in ms + int empty; }; uniform int current_depth; @@ -67,17 +68,21 @@ TileColor get_tile_color(vec3 pos, int depth) { if (uniq == textures_tiles[i].uniq) { Tile tile = textures_tiles[i]; - int idx_texture = tile.texture_idx >> 6; - int off = tile.texture_idx % 64; - float idx_row = float(off >> 3); // in [0; 7] - float idx_col = float(off % 8); // in [0; 7] + if (tile.empty == 1) { + return TileColor(tile, vec3(0.0), true); + } else { + int idx_texture = tile.texture_idx >> 6; + int off = tile.texture_idx % 64; + float idx_row = float(off >> 3); // in [0; 7] + float idx_col = float(off % 8); // in [0; 7] - vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; - vec3 UV = vec3(offset, float(idx_texture)); + vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; + vec3 UV = vec3(offset, float(idx_texture)); - vec3 color = K * C * get_grayscale_from_texture(UV); + vec3 color = K * C * get_grayscale_from_texture(UV); - return TileColor(tile, color, true); + return TileColor(tile, color, true); + } } else if (uniq < textures_tiles[i].uniq) { // go to left b = i - 1; @@ -89,7 +94,7 @@ TileColor get_tile_color(vec3 pos, int depth) { } // code unreachable - Tile empty = Tile(0, -1, current_time); + Tile empty = Tile(0, -1, current_time, 1); return TileColor(empty, vec3(0.f), false); } diff --git a/src/render/src/shaders/hips/raytracer/grayscale_to_color_i.frag b/src/render/src/shaders/hips/raytracer/grayscale_to_color_i.frag index c90faac1..95f6ba79 100644 --- a/src/render/src/shaders/hips/raytracer/grayscale_to_color_i.frag +++ b/src/render/src/shaders/hips/raytracer/grayscale_to_color_i.frag @@ -15,6 +15,7 @@ struct Tile { int uniq; // Healpix cell int texture_idx; // Index in the texture buffer float start_time; // Absolute time that the load has been done in ms + int empty; }; uniform int current_depth; @@ -67,17 +68,20 @@ TileColor get_tile_color(vec3 pos, int depth) { if (uniq == textures_tiles[i].uniq) { Tile tile = textures_tiles[i]; - int idx_texture = tile.texture_idx >> 6; - int off = tile.texture_idx % 64; - float idx_row = float(off >> 3); // in [0; 7] - float idx_col = float(off % 8); // in [0; 7] + if (tile.empty == 1) { + return TileColor(tile, vec3(0.0), true); + } else { + int idx_texture = tile.texture_idx >> 6; + int off = tile.texture_idx % 64; + float idx_row = float(off >> 3); // in [0; 7] + float idx_col = float(off % 8); // in [0; 7] - vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; - vec3 UV = vec3(offset, float(idx_texture)); + vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; + vec3 UV = vec3(offset, float(idx_texture)); - vec3 color = K * C * get_grayscale_from_texture(UV); - - return TileColor(tile, color, true); + vec3 color = K * C * get_grayscale_from_texture(UV); + return TileColor(tile, color, true); + } } else if (uniq < textures_tiles[i].uniq) { // go to left b = i - 1; @@ -89,8 +93,8 @@ TileColor get_tile_color(vec3 pos, int depth) { } // code unreachable - Tile empty = Tile(0, -1, current_time); - return TileColor(empty, vec3(0.f), false); + Tile empty = Tile(0, -1, current_time, 1); + return TileColor(empty, vec3(0.0, 0.0, 1.0), false); } const float duration = 500.f; // 500ms diff --git a/src/render/src/shaders/hips/raytracer/grayscale_to_colormap.frag b/src/render/src/shaders/hips/raytracer/grayscale_to_colormap.frag index 559c93c8..81a1bd0a 100644 --- a/src/render/src/shaders/hips/raytracer/grayscale_to_colormap.frag +++ b/src/render/src/shaders/hips/raytracer/grayscale_to_colormap.frag @@ -15,6 +15,7 @@ struct Tile { int uniq; // Healpix cell int texture_idx; // Index in the texture buffer float start_time; // Absolute time that the load has been done in ms + int empty; }; uniform int current_depth; @@ -61,18 +62,21 @@ TileColor get_tile_color(vec3 pos, int depth) { for(int step = 0; step < h; step++) { if (uniq == textures_tiles[i].uniq) { Tile tile = textures_tiles[i]; + if (tile.empty == 1) { + return TileColor(tile, vec3(0.0), true); + } else { + int idx_texture = tile.texture_idx >> 6; + int off = tile.texture_idx % 64; + float idx_row = float(off >> 3); // in [0; 7] + float idx_col = float(off % 8); // in [0; 7] - int idx_texture = tile.texture_idx >> 6; - int off = tile.texture_idx % 64; - float idx_row = float(off >> 3); // in [0; 7] - float idx_col = float(off % 8); // in [0; 7] + vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; + vec3 UV = vec3(offset, float(idx_texture)); - vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; - vec3 UV = vec3(offset, float(idx_texture)); + vec3 color = colormap_f(get_grayscale_from_texture(UV)).rgb; - vec3 color = colormap_f(get_grayscale_from_texture(UV)).rgb; - - return TileColor(tile, color, true); + return TileColor(tile, color, true); + } } else if (uniq < textures_tiles[i].uniq) { // go to left b = i - 1; @@ -84,7 +88,7 @@ TileColor get_tile_color(vec3 pos, int depth) { } // code unreachable - Tile empty = Tile(0, -1, current_time); + Tile empty = Tile(0, -1, current_time, 1); return TileColor(empty, vec3(0.f), false); } diff --git a/src/render/src/shaders/hips/raytracer/grayscale_to_colormap_i.frag b/src/render/src/shaders/hips/raytracer/grayscale_to_colormap_i.frag index ca0e76a2..e42229bf 100644 --- a/src/render/src/shaders/hips/raytracer/grayscale_to_colormap_i.frag +++ b/src/render/src/shaders/hips/raytracer/grayscale_to_colormap_i.frag @@ -15,6 +15,7 @@ struct Tile { int uniq; // Healpix cell int texture_idx; // Index in the texture buffer float start_time; // Absolute time that the load has been done in ms + int empty; }; uniform int current_depth; @@ -61,18 +62,21 @@ TileColor get_tile_color(vec3 pos, int depth) { for(int step = 0; step < h; step++) { if (uniq == textures_tiles[i].uniq) { Tile tile = textures_tiles[i]; + if (tile.empty == 1) { + return TileColor(tile, vec3(0.0), true); + } else { + int idx_texture = tile.texture_idx >> 6; + int off = tile.texture_idx % 64; + float idx_row = float(off >> 3); // in [0; 7] + float idx_col = float(off % 8); // in [0; 7] - int idx_texture = tile.texture_idx >> 6; - int off = tile.texture_idx % 64; - float idx_row = float(off >> 3); // in [0; 7] - float idx_col = float(off % 8); // in [0; 7] + vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; + vec3 UV = vec3(offset, float(idx_texture)); - vec2 offset = (vec2(idx_col, idx_row) + uv)/8.f; - vec3 UV = vec3(offset, float(idx_texture)); + vec3 color = colormap_f(get_grayscale_from_texture(UV)).rgb; - vec3 color = colormap_f(get_grayscale_from_texture(UV)).rgb; - - return TileColor(tile, color, true); + return TileColor(tile, color, true); + } } else if (uniq < textures_tiles[i].uniq) { // go to left b = i - 1; @@ -84,7 +88,7 @@ TileColor get_tile_color(vec3 pos, int depth) { } // code unreachable - Tile empty = Tile(0, -1, current_time); + Tile empty = Tile(0, -1, current_time, 1); return TileColor(empty, vec3(0.f), false); }