diff --git a/src/core/src/renderable/hips/d3/buffer.rs b/src/core/src/renderable/hips/d3/buffer.rs index f16cafca..46ac7338 100644 --- a/src/core/src/renderable/hips/d3/buffer.rs +++ b/src/core/src/renderable/hips/d3/buffer.rs @@ -185,36 +185,14 @@ impl HpxTileBuffer for HiPS3DBuffer { } } -/* +use al_core::shader::SendUniforms; +use al_core::shader::ShaderBound; impl SendUniforms for HiPS3DBuffer { // Send only the allsky textures fn attach_uniforms<'a>(&self, shader: &'a ShaderBound<'a>) -> &'a ShaderBound<'a> { - // Send the textures - /*let textures = &self.base_textures; - for (idx, texture) in textures.iter().enumerate() { - let texture_uniforms = TextureUniforms::new(texture, idx as i32); - shader.attach_uniforms_from(&texture_uniforms); - }*/ - - //if self.raytracing { - for idx in 0..NUM_HPX_TILES_DEPTH_ZERO { - let cell = HEALPixCell(0, idx as u64); - - let texture = self.get(&cell).unwrap(); - let texture_uniforms = TextureUniforms::new(texture, idx as i32); - shader.attach_uniforms_from(&texture_uniforms); - } - //} - - let shader = shader - .attach_uniforms_from(&self.config) - .attach_uniform("tex", &self.texture_2d_array) - .attach_uniform("num_slices", &(self.texture_2d_array.num_slices as i32)); - - shader + shader.attach_uniforms_from(&self.config) } } -*/ impl Drop for HiPS3DBuffer { fn drop(&mut self) { diff --git a/src/core/src/renderable/hips/d3/mod.rs b/src/core/src/renderable/hips/d3/mod.rs index 690c01e2..7b794692 100644 --- a/src/core/src/renderable/hips/d3/mod.rs +++ b/src/core/src/renderable/hips/d3/mod.rs @@ -580,14 +580,14 @@ impl HiPS3D { // * there are new available tiles for the GPU let mut off_idx = 0; + let shader = get_raster_shader(cmap, &self.gl, shaders, &hips_cfg)?.bind(&self.gl); + for (slice_idx, (cell, num_indices)) in self .slice_indices .iter() .zip(self.cells.iter().zip(self.num_indices.iter())) { blend_cfg.enable(&self.gl, || { - let shader = get_raster_shader(cmap, &self.gl, shaders, &hips_cfg)?.bind(&self.gl); - shader .attach_uniform( "tex", @@ -597,6 +597,7 @@ impl HiPS3D { .get_3d_block_from_slice(*slice_idx as u16) .unwrap(), ) + .attach_uniforms_from(&self.buffer) .attach_uniforms_with_params_from(cmap, colormaps) .attach_uniforms_from(color) .attach_uniforms_from(camera) diff --git a/src/core/src/renderable/hips/d3/texture.rs b/src/core/src/renderable/hips/d3/texture.rs index 0d6ac415..e27d3d32 100644 --- a/src/core/src/renderable/hips/d3/texture.rs +++ b/src/core/src/renderable/hips/d3/texture.rs @@ -80,8 +80,6 @@ impl HpxTexture3D { }; let m1 = (!m2) & !(1 << (31 - slice_idx)); - al_core::log(&format!("m1 {:#x} m2 {:#x} {:?}", m1, m2, slice_idx)); - let lb = ((block & m1) >> (32 - slice_idx)) as u32; let rb = (block & m2) as u32; @@ -91,15 +89,6 @@ impl HpxTexture3D { let no_more_left_bits = slice_idx - (lb_trailing_zeros as u32) == 0; let no_more_right_bits = slice_idx + (rb_leading_zeros as u32) == 31; - al_core::log(&format!( - "{:?} {:?} slice idx {:?}, {:x?} rb {:?}", - no_more_left_bits, - no_more_right_bits, - slice_idx, - lb, - lb_trailing_zeros as u32 - )); - match (no_more_left_bits, no_more_right_bits) { (false, false) => { if lb_trailing_zeros <= rb_leading_zeros { diff --git a/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap.frag b/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap.frag index 989366c2..8e41e0c1 100644 --- a/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap.frag +++ b/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap.frag @@ -15,7 +15,7 @@ out vec4 out_frag_color; uniform float opacity; void main() { - vec4 color = get_colormap_from_grayscale_texture(frag_uv); + vec4 color = get_colormap_from_grayscale_texture(vec3(frag_uv.xy, mod(frag_uv.z, 32.0) / 32.0)); out_frag_color = color; out_frag_color.a = out_frag_color.a * opacity; diff --git a/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap_i.frag b/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap_i.frag index 39960350..79acff48 100644 --- a/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap_i.frag +++ b/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap_i.frag @@ -15,7 +15,7 @@ out vec4 out_frag_color; uniform float opacity; void main() { - vec4 color = get_colormap_from_grayscale_texture(frag_uv); + vec4 color = get_colormap_from_grayscale_texture(vec3(frag_uv.xy, mod(frag_uv.z, 32.0) / 32.0)); out_frag_color = color; out_frag_color.a = out_frag_color.a * opacity; diff --git a/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap_u.frag b/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap_u.frag index 8482d245..712adfe5 100644 --- a/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap_u.frag +++ b/src/glsl/webgl2/hips3d/rasterizer/grayscale_to_colormap_u.frag @@ -15,7 +15,7 @@ out vec4 out_frag_color; uniform float opacity; void main() { - vec4 color = get_colormap_from_grayscale_texture(frag_uv); + vec4 color = get_colormap_from_grayscale_texture(vec3(frag_uv.xy, mod(frag_uv.z, 32.0) / 32.0)); out_frag_color = color; out_frag_color.a = out_frag_color.a * opacity; diff --git a/src/js/Aladin.js b/src/js/Aladin.js index 812aed2c..dd023716 100644 --- a/src/js/Aladin.js +++ b/src/js/Aladin.js @@ -1442,6 +1442,13 @@ export let Aladin = (function () { // see MOC.setView for sending it to outside the UI }; + Aladin.prototype.removeUIByName = function(name) { + let elt = this.ui.find((elm) => elm.name === name) + if (elt) { + elt.remove() + } + }; + Aladin.prototype.addUI = function (ui) { ui = [].concat(ui); diff --git a/src/js/HiPS.js b/src/js/HiPS.js index 78268b59..1c382585 100644 --- a/src/js/HiPS.js +++ b/src/js/HiPS.js @@ -197,6 +197,8 @@ export let HiPS = (function () { this.name = (options && options.name) || undefined; this.startUrl = options.startUrl; + this.slice = 0; + if (location instanceof FileList) { let localFiles = {}; for (var file of location) { @@ -290,6 +292,7 @@ export let HiPS = (function () { // Cube depth self.cubeDepth = properties && properties.hips_cube_depth && +properties.hips_cube_depth; + self.cubeFirstFrame = properties && properties.hips_cube_firstframe && +properties.hips_cube_firstframe; // Max order self.maxOrder = @@ -707,6 +710,8 @@ export let HiPS = (function () { }; HiPS.prototype.setSliceNumber = function(slice) { + this.slice = slice; + if (this.added) { this.view.wasm.setSliceNumber(this.layer, slice); } @@ -1012,6 +1017,8 @@ export let HiPS = (function () { return Promise.resolve(this) .then((hips) => { + this.added = true; + if (hips.successCallback) { hips.successCallback(hips) } diff --git a/src/js/MocServer.js b/src/js/MocServer.js index fdf2136f..427ded8a 100644 --- a/src/js/MocServer.js +++ b/src/js/MocServer.js @@ -47,8 +47,8 @@ export class MocServer { static getAllHiPSes() { if (!this._allHiPSes) { const params = { - //expr: "dataproduct_type=image||dataproduct_type=cube", - expr: "dataproduct_type=image", + expr: "dataproduct_type=image||dataproduct_type=cube", + //expr: "dataproduct_type=image", get: "record", fmt: "json", fields: "ID,hips_creator,hips_copyright,hips_order,hips_tile_width,hips_frame,hips_tile_format,obs_title,obs_description,obs_copyright,obs_regime", diff --git a/src/js/View.js b/src/js/View.js index 9854d5b1..c9aeefe5 100644 --- a/src/js/View.js +++ b/src/js/View.js @@ -1693,7 +1693,7 @@ export let View = (function () { this.imageLayers.delete(layerName); } - imageLayer.added = true; + //imageLayer.added = true; this.imageLayers.set(layerName, imageLayer); diff --git a/src/js/gui/Box/HiPSBrowserBox.js b/src/js/gui/Box/HiPSBrowserBox.js index 9feb3591..441bf774 100644 --- a/src/js/gui/Box/HiPSBrowserBox.js +++ b/src/js/gui/Box/HiPSBrowserBox.js @@ -283,13 +283,104 @@ export class HiPSBrowserBox extends Box { self.searchDropdown.removeClass('aladin-not-valid'); self.searchDropdown.addClass('aladin-valid'); - self.infoCurrentHiPSBtn.update({ disable: false, action(e) { window.open(hips.url); } }) + + if (!hips.cubeDepth) + return; + + let numSlices = hips.cubeDepth; + let idxSlice = hips.cubeFirstFrame; + + hips.setSliceNumber(idxSlice) + + let toStr = (n, paddingBegin = false) => { + let s = n.toString(); + let maxNumDigits = numSlices.toString().length; + + if (s.length < maxNumDigits) { + let r = ' '.repeat(maxNumDigits - s.length) + if (paddingBegin) { + s = r + s + } else { + s += r + } + } + + return s; + } + + let updateSlice = () => { + slicer.update({ + value: idxSlice, + tooltip: {content: (idxSlice + 1) + '/' + numSlices, position: {direction: 'bottom'}}, + }) + + hips.setSliceNumber(idxSlice) + cubeDisplayer.update({position: cubeDisplayer.position, content: Layout.horizontal([prevBtn, nextBtn, slicer, toStr(idxSlice + 1, true) + '/' + toStr(numSlices, false)])}) + }; + + let slicer = Input.slider({ + label: "Slice", + name: "cube slicer", + ticks: [idxSlice], + tooltip: {content: (idxSlice + 1) + '/' + numSlices, position: {direction: 'bottom'}}, + min: 0, + max: numSlices - 1, + value: idxSlice, + actions: { + change: (e) => { + idxSlice = Math.round(e.target.value); + + updateSlice(); + }, + input: (e) => { + idxSlice = Math.round(e.target.value); + + slicer.update({ + value: idxSlice, + tooltip: {content: (idxSlice + 1) + '/' + numSlices, position: {direction: 'bottom'}}, + }) + } + }, + cssStyle: { + width: '300px' + } + }); + + let prevBtn = A.button({ + size: 'small', + content: '<', + action(o) { + idxSlice = Math.max(idxSlice - 1, 0); + updateSlice() + } + }) + + let nextBtn = A.button({ + size: 'small', + content: '>', + action(o) { + idxSlice = Math.min(idxSlice + 1, numSlices - 1); + updateSlice() + } + }) + + let cubeDisplayer = A.box({ + close: true, + name: 'player' + hips.name, + header: { + title: 'Player for: ' + hips.name, + draggable: true, + }, + content: Layout.horizontal([prevBtn, nextBtn, slicer, toStr(idxSlice + 1, true) + '/' + toStr(numSlices, false)]), + position: {anchor: 'center top'}, + }); + self.aladin.addUI(cubeDisplayer) }, errorCallback: (e) => { self.searchDropdown.removeClass('aladin-valid'); diff --git a/src/js/gui/Box/StackBox.js b/src/js/gui/Box/StackBox.js index ebdb46dd..0ddf4f53 100644 --- a/src/js/gui/Box/StackBox.js +++ b/src/js/gui/Box/StackBox.js @@ -964,6 +964,8 @@ export class OverlayStackBox extends Box { tooltip: { content: "Remove", position: { direction: "top" } }, action(e) { self.aladin.removeImageLayer(layer.layer); + // remove HiPS cube player if any + self.aladin.removeUIByName("player" + layer.name) }, }); diff --git a/src/js/gui/Widgets/Selector.js b/src/js/gui/Widgets/Selector.js index ecc1908d..a4c7a167 100644 --- a/src/js/gui/Widgets/Selector.js +++ b/src/js/gui/Widgets/Selector.js @@ -21,7 +21,6 @@ import { DOMElement } from "./Widget"; import { FSM } from "../../FiniteStateMachine"; import { ActionButton } from "./ActionButton"; import { ContextMenu } from "./ContextMenu"; -import { Layout } from "../Layout"; /****************************************************************************** * Aladin Lite project diff --git a/src/js/gui/Widgets/Widget.js b/src/js/gui/Widgets/Widget.js index 8fa75a2a..74823e24 100644 --- a/src/js/gui/Widgets/Widget.js +++ b/src/js/gui/Widgets/Widget.js @@ -17,6 +17,8 @@ // along with Aladin Lite. // +import { Utils } from "../../Utils"; + /****************************************************************************** * Aladin Lite project * @@ -43,6 +45,7 @@ export class DOMElement { this.el = element; this.options = options; + this.name = options && options.name || Utils.uuidv4() this.isHidden = true; }