From c81fbb6618c28aaad6a68cf9aa449e46fec25a30 Mon Sep 17 00:00:00 2001 From: Matthieu Baumann Date: Wed, 16 Sep 2020 18:00:14 +0200 Subject: [PATCH] setImageSurvey in progress --- dist/index.html | 3 +- src/js/Aladin.js | 70 ++++++----- src/js/HpxImageSurvey.js | 145 ++++++++++++----------- src/js/View.js | 112 ++++++++--------- src/render/src/buffer/hips_config.rs | 37 +++++- src/render/src/buffer/image.rs | 2 +- src/render/src/lib.rs | 14 +-- src/render/src/renderable/hips_sphere.rs | 9 +- 8 files changed, 215 insertions(+), 177 deletions(-) diff --git a/dist/index.html b/dist/index.html index 498c7749..3855e822 100644 --- a/dist/index.html +++ b/dist/index.html @@ -22,8 +22,9 @@ let aladin; A.init.then(() => { + console.log("then of init") // Start up Aladin Lite - aladin = A.aladin('#aladin-lite-div', {target: 'M51', fov: 0.3, survey: 'P/DSS2/red'}); + aladin = A.aladin('#aladin-lite-div', {target: 'M51', fov: 0.3, survey: 'CDS/P/DSS2/red'}); }); diff --git a/src/js/Aladin.js b/src/js/Aladin.js index b6c6eb2e..d0ac9e92 100644 --- a/src/js/Aladin.js +++ b/src/js/Aladin.js @@ -49,10 +49,6 @@ import { Coo } from "./libs/astro/coo.js"; import { CooConversion } from "./CooConversion.js"; import { ColorMap } from "./ColorMap.js"; import { URLBuilder } from "./URLBuilder.js"; -import { loadShaders } from './Shaders.js'; - -// Import kernel image -import kernel from './../render/img/kernel.png'; export let Aladin = (function () { @@ -62,6 +58,7 @@ export let Aladin = (function () { if ($(aladinDiv).length == 0) { return; } + this.webglAPI = null; var self = this; @@ -303,7 +300,25 @@ export let Aladin = (function () { this.createCatalogFromVOTable(options.catalogUrls[k]); } } - console.log(options.survey) + console.log("SURVEYYYY: ", options.survey) + + /*let webglAPI = await import('../render/pkg/'); + console.log('webgl imported'); + let shaders = await loadShaders(webglAPI); + console.log(shaders); + + // Start our Rust application. You can find `WebClient` in `src/lib.rs` + let resources = { + 'kernel': kernel, + }; + Aladin.wasmLibs.webglAPI = new webglAPI.WebClient(shaders, resources); + let webgl = Aladin.wasmLibs.webglAPI; + webgl.resize(500, 400);*/ + + /*let imageSurveyInfo = HpxImageSurvey.getSurveyInfoFromId(options.survey); + console.log('image survey, ', imageSurveyInfo) + webgl.setImageSurvey(imageSurveyInfo);*/ + this.setImageSurvey(options.survey); this.view.showCatalog(options.showCatalog); @@ -346,9 +361,10 @@ export let Aladin = (function () { if (options.fullScreen) { window.setTimeout(function () { self.toggleFullscreen(self.options.realFullscreen); }, 1000); } - this.webglAPI = undefined; this.callbacksByEventName = {}; // we store the callback functions (on 'zoomChanged', 'positionChanged', ...) here + + this.view.redraw(); }; /**** CONSTANTS ****/ @@ -886,9 +902,8 @@ export let Aladin = (function () { // @param imageSurvey : HpxImageSurvey object or image survey identifier // @api // @old - Aladin.prototype.setImageSurvey = function (imageSurvey, callback) { - console.log("sdfsdfsdf") - this.view.setImageSurvey(imageSurvey, callback); + Aladin.prototype.setImageSurvey = function (imageSurvey) { + this.view.setImageSurvey(imageSurvey); this.updateSurveysDropdownList(HpxImageSurvey.getAvailableSurveys()); if (this.options.log) { var id = imageSurvey; @@ -1694,34 +1709,15 @@ A.catalogFromSkyBot = function (ra, dec, radius, epoch, queryOptions, options, s return A.catalogFromURL(url, options, successCallback, false); }; -A.init = new Promise((resolutionFunc, rejectionFunc) => { - // HEALPix wasm library - import('@fxpineau/healpix') - .then(hpxAPI => { - Aladin.wasmLibs.hpx = hpxAPI; - resolutionFunc(); - }) - .catch(console.error); - }).then(() => { - // WebGL API - import('../render/pkg/') - .then(async (webglAPI) => { - let shaders = await loadShaders(webglAPI); - console.log(shaders); - - // Start our Rust application. You can find `WebClient` in `src/lib.rs` - let resources = { - 'kernel': kernel, - }; - //Aladin.webglAPI = - let webgl = Aladin.wasmLibs.webglAPI; - webgl = new webglAPI.WebClient(shaders, resources); - webgl.resize(500, 400); - console.log("imazaz", HpxImageSurvey.SURVEYS[1]); - webgl.setImageSurvey(HpxImageSurvey.SURVEYS[1]); - }) - .catch(console.error); - }); +A.init = Promise.all([import('@fxpineau/healpix'), import('../render/pkg/')]).then(async (values) => { + console.log(values); + let [hpxAPI, webglAPI] = values; + + // HEALPix library + Aladin.wasmLibs.hpx = hpxAPI; + // WebGL library + Aladin.wasmLibs.webgl = webglAPI; +}); // this is ugly for sure and there must be a better way using Webpack magic window.A = A; diff --git a/src/js/HpxImageSurvey.js b/src/js/HpxImageSurvey.js index 7658443b..c40d5a12 100644 --- a/src/js/HpxImageSurvey.js +++ b/src/js/HpxImageSurvey.js @@ -35,6 +35,7 @@ import { HpxKey } from "./HpxKey.js"; import { CooFrameEnum } from "./CooFrameEnum.js"; import { Tile } from "./Tile.js"; import { Aladin } from "./Aladin.js"; +import { call } from "file-loader"; export let HpxImageSurvey = (function() { @@ -44,38 +45,37 @@ export let HpxImageSurvey = (function() { * They will be determined by reading the properties file * */ - let HpxImageSurvey = function(rootURLOrHiPSDefinition, options) { - // new way - if (rootURLOrHiPSDefinition instanceof HiPSDefinition) { - this.hipsDefinition = rootURLOrHiPSDefinition; - // TODO - this.FromHiPSDefinition(rootURLOrHiPSDefinition, options); + + let HpxImageSurvey = function(rootURL, options, callback) { + // Use the url for retrieving the HiPS properties + // remove final slash + if (rootURL.slice(-1) === '/') { + this.rootUrl = rootURL.substr(0, rootURL.length-1); } else { - // Use the url for retrieving the HiPS properties - // remove final slash - if (rootURLOrHiPSDefinition.slice(-1) === '/') { - this.rootUrl = rootURLOrHiPSDefinition.substr(0, rootURLOrHiPSDefinition.length-1); - } - else { - this.rootUrl = rootURLOrHiPSDefinition; - } - // make URL absolute - this.rootUrl = Utils.getAbsoluteURL(this.rootUrl); - - // fast fix for HTTPS support --> will work for all HiPS served by CDS - if (Utils.isHttpsContext() && ( /u-strasbg.fr/i.test(this.rootUrl) || /unistra.fr/i.test(this.rootUrl) ) ) { - this.rootUrl = this.rootUrl.replace('http://', 'https://'); - } - - console.log("URL: ", rootURLOrHiPSDefinition) - this.hipsDefinition = HiPSDefinition.fromURL(this.rootUrl, (hipsDefinition) => { - console.log("hips def ,", hipsDefinition) - - this.FromHiPSDefinition(hipsDefinition, options); - }); + this.rootUrl = rootURL; } + + // make URL absolute + this.rootUrl = Utils.getAbsoluteURL(this.rootUrl); + + // fast fix for HTTPS support --> will work for all HiPS served by CDS + if (Utils.isHttpsContext() && ( /u-strasbg.fr/i.test(this.rootUrl) || /unistra.fr/i.test(this.rootUrl) ) ) { + this.rootUrl = this.rootUrl.replace('http://', 'https://'); + } + + console.log("URL: ", rootURL) + HiPSDefinition.fromURL(this.rootUrl, (hipsDefinition) => { + console.log("hips def ,", hipsDefinition) + + this.FromHiPSDefinition(hipsDefinition, options); + + if (callback) { + callback(this.getSurveyInfo()); + } + }); + // REPRENDRE LA, EN CREANT l'OBJET HiPSDefinition ou FAIRE dans l'autre sens // old way, we retrofit parameters into a HiPSDefinition object /*var hipsDefProps = {}; @@ -128,16 +128,14 @@ export let HpxImageSurvey = (function() { }; - HpxImageSurvey.prototype.FromHiPSDefinition = function(hipsDefinition, options) { this.id = hipsDefinition.getID(); this.name = hipsDefinition.properties["obs_title"]; this.minOrder = hipsDefinition.properties["hips_order_min"]; - this.tileSize = hipsDefinition.properties["hips_tile_width"]; - this.maxOrder = hipsDefinition.properties["hips_order"]; + this.tileSize = +hipsDefinition.properties["hips_tile_width"]; + this.maxOrder = +hipsDefinition.properties["hips_order"]; this.cooFrame = CooFrameEnum.fromString(hipsDefinition.properties["hips_frame"], CooFrameEnum.J2000); - console.log(hipsDefinition.properties) this.imgFormat = hipsDefinition.properties["hips_tile_format"]; this.minCutout = 0.0; this.maxCutout = 1.0; @@ -158,7 +156,9 @@ export let HpxImageSurvey = (function() { if (this.rootUrl.indexOf('/glimpse360/aladin/data')>=0) { this.cooFrame = CooFrameEnum.J2000; } - this.longitudeReversed = options.longitudeReversed || false; + if (options) { + this.longitudeReversed = options.longitudeReversed || false; + } this.hipsDefinition = hipsDefinition; @@ -170,15 +170,13 @@ export let HpxImageSurvey = (function() { this.lastUpdateDateNeededTiles = 0; var found = false; - let imageSurvey = null; for (var k=0; k=0 ) { options.imgFormat = 'png'; } - return new HpxImageSurvey(surveyInfo.url, options); + return new HpxImageSurvey(surveyInfo.url, options, callback); } return null; diff --git a/src/js/View.js b/src/js/View.js index 862732e4..c2c84d72 100644 --- a/src/js/View.js +++ b/src/js/View.js @@ -50,7 +50,9 @@ import { Circle } from "./Circle.js"; import { CooFrameEnum } from "./CooFrameEnum.js"; import { CooConversion } from "./CooConversion.js"; import { requestAnimFrame } from "./libs/RequestAnimationFrame.js"; -import { load_shaders } from './Shaders.js'; +import { loadShaders } from './Shaders.js'; +// Import kernel image +import kernel from './../render/img/kernel.png'; export let View = (function() { @@ -64,6 +66,18 @@ export let View = (function() { this.popup = new Popup(this.aladinDiv, this); this.createCanvases(); + // Init the WebGL context + // At this point, the view has been created so the image canvas too + let shaders = loadShaders(Aladin.wasmLibs.webgl); + console.log(shaders); + + // Start our Rust application. You can find `WebClient` in `src/lib.rs` + let resources = { + 'kernel': kernel, + }; + this.aladin.webglAPI = new Aladin.wasmLibs.webgl.WebClient(shaders, resources); + this.aladin.webglAPI.resize(500, 400); + this.location = location; this.fovDiv = fovDiv; this.mustClearCatalog = true; @@ -241,10 +255,7 @@ export let View = (function() { // reinitialize 2D context this.imageCtx = this.imageCanvas.getContext("webgl2"); - let webglAPI = Aladin.wasmLibs.webglAPI; - if (webglAPI) { - webglAPI.resize(this.width, this.height); - } + this.aladin.webglAPI.resize(this.width, this.height); this.catalogCtx = this.catalogCanvas.getContext("2d"); this.reticleCtx = this.reticleCanvas.getContext("2d"); @@ -406,7 +417,7 @@ export let View = (function() { //var xy = AladinUtils.viewToXy(xymouse.x, xymouse.y, view.width, view.height, view.largestDim, view.zoomFactor); try { - var lonlat = Aladin.wasmLibs.webglAPI.screenToWorld(xymouse.x, xymouse.y); + var lonlat = view.aladin.webglAPI.screenToWorld(xymouse.x, xymouse.y); } catch(err) { return; @@ -607,6 +618,7 @@ export let View = (function() { }); var lastHoveredObject; // save last object hovered by mouse var lastMouseMovePos = null; + let webglAPI = view.aladin.webglAPI; $(view.reticleCanvas).bind("mousemove touchmove", function(e) { e.preventDefault(); @@ -679,8 +691,8 @@ export let View = (function() { //pos1 = view.projection.unproject(xy1.x, xy1.y); //pos2 = view.projection.unproject(xy2.x, xy2.y); - pos1 = Aladin.wasmLibs.webglAPI.screenToWorld(view.dragx, view.dragy); - pos2 = Aladin.wasmLibs.webglAPI.screenToWorld(e.originalEvent.targetTouches[0].clientX, e.originalEvent.targetTouches[0].clientY); + pos1 = webglAPI.screenToWorld(view.dragx, view.dragy); + pos2 = webglAPI.screenToWorld(e.originalEvent.targetTouches[0].clientX, e.originalEvent.targetTouches[0].clientY); } else { /* @@ -694,8 +706,10 @@ export let View = (function() { //pos1 = view.projection.unproject(xy1.x, xy1.y); //pos2 = view.projection.unproject(xy2.x, xy2.y); - pos1 = Aladin.wasmLibs.webglAPI.screenToWorld(view.dragx, view.dragy); - pos2 = Aladin.wasmLibs.webglAPI.screenToWorld(xymouse.x, xymouse.y); + console.log("ALADIN LITE, ",webglAPI) + + pos1 = webglAPI.screenToWorld(view.dragx, view.dragy); + pos2 = webglAPI.screenToWorld(xymouse.x, xymouse.y); } // TODO : faut il faire ce test ?? @@ -749,13 +763,11 @@ export let View = (function() { view.viewCenter.lon = view.viewCenter.lon % 360; } view.realDragging = true; - let webglAPI = Aladin.wasmLibs.webglAPI; - if (webglAPI) { - webglAPI.moveView(pos1[0], pos1[1], pos2[0], pos2[1]); - //webglAPI.setCenter(pos2[0], pos2[1]); - view.viewCenter.lon = pos2[0]; - view.viewCenter.lat = pos2[1]; - } + + webglAPI.moveView(pos1[0], pos1[1], pos2[0], pos2[1]); + //webglAPI.setCenter(pos2[0], pos2[1]); + view.viewCenter.lon = pos2[0]; + view.viewCenter.lat = pos2[1]; view.requestRedraw(); }); //// endof mousemove //// @@ -839,8 +851,8 @@ export let View = (function() { // initial draw view.fov = computeFov(view); updateFovDiv(view); - - view.redraw(); + console.log("first DRAW") + //view.redraw(); }; function updateLocation(view, x, y, isViewCenterPosition) { @@ -910,12 +922,9 @@ export let View = (function() { requestAnimFrame(this.redraw.bind(this)); var now = Date.now(); var dt = now - this.prev; - let webglAPI = Aladin.wasmLibs.webglAPI; - if (!webglAPI) { - return; - } - let tasksFinished = webglAPI.runTasks(dt); - let updateView = webglAPI.update(dt); + + let tasksFinished = this.aladin.webglAPI.runTasks(dt); + let updateView = this.aladin.webglAPI.update(dt); if (this.dateRequestDraw && now>this.dateRequestDraw) { this.dateRequestDraw = null; @@ -930,7 +939,7 @@ export let View = (function() { } //this.stats.update(); - webglAPI.render(); + this.aladin.webglAPI.render(); var imageCtx = this.imageCtx; //////// 1. Draw images //////// @@ -1561,10 +1570,7 @@ export let View = (function() { var oldFov = this.fov; this.fov = computeFov(this); console.log("FOV, ", this.fov); - let webglAPI = Aladin.wasmLibs.webglAPI; - if (webglAPI) { - webglAPI.setFieldOfView(this.fov); - } + this.aladin.webglAPI.setFieldOfView(this.fov); // TODO: event/listener should be better updateFovDiv(this); @@ -1680,7 +1686,7 @@ export let View = (function() { var unknownSurveyId = undefined; // @param imageSurvey : HpxImageSurvey object or image survey identifier - View.prototype.setImageSurvey = function(imageSurvey, callback) { + View.prototype.setImageSurvey = function(imageSurvey) { if (! imageSurvey) { return; } @@ -1690,35 +1696,24 @@ export let View = (function() { if ($.support.cors && this.imageSurvey && ! this.imageSurvey.useCors) { this.untaintCanvases(); } - + console.log('type imageSurvey', typeof imageSurvey); var newImageSurvey; if (typeof imageSurvey == "string") { - newImageSurvey = HpxImageSurvey.getSurveyFromId(imageSurvey); - if ( ! newImageSurvey) { - newImageSurvey = HpxImageSurvey.getSurveyFromId(HpxImageSurvey.DEFAULT_SURVEY_ID); - unknownSurveyId = imageSurvey; + // imageSurvey is an ID + newImageSurvey = HpxImageSurvey.getSurveyFromId(imageSurvey, (imageSurveyProperties) => { + console.log('set HiPS info', imageSurveyProperties) + this.aladin.webglAPI.setImageSurvey(imageSurveyProperties); + }); + if (newImageSurvey) { + this.imageSurvey = newImageSurvey; + } else { + throw imageSurvey + ' id not a valid image survey ID'; } } else { + // image survey is an HpxImageSurvey so it is in HpxImageSurvey.SURVEYS list newImageSurvey = imageSurvey; } - - let webglAPI = Aladin.wasmLibs.webglAPI; - if (webglAPI) { - let imageSurveys = HpxImageSurvey.getAvailableSurveys(); - let hipsDefinition = null; - for (var k=0; k Result<(), JsValue> { + crate::log(&format!("new hips config {:?}", hips_def)); + + let fmt = hips_def.format; + let format : Result<_, JsValue> = if fmt.contains("fits") { + // Check the bitpix to determine the internal format of the tiles + match hips_def.bitpix { + 8 => Ok(FormatImageType::FITS(FITS::new(WebGl2RenderingContext::R8UI as i32))), + 16 => Ok(FormatImageType::FITS(FITS::new(WebGl2RenderingContext::R16I as i32))), + 32 => Ok(FormatImageType::FITS(FITS::new(WebGl2RenderingContext::R32I as i32))), + -32 => Ok(FormatImageType::FITS(FITS::new(WebGl2RenderingContext::R32F as i32))), + _ => { + // The bitpix is not good, so we check for jpeg or png tiles + if fmt.contains("png") { + Ok(FormatImageType::PNG) + } else if fmt.contains("jpeg") || fmt.contains("jpg") { + Ok(FormatImageType::JPG) + } else { + Err(format!("Fits tiles exists but the BITPIX is not correct in the property file").into()) + } + } + } + } else if fmt.contains("png") { + Ok(FormatImageType::PNG) + } else if fmt.contains("jpeg") || fmt.contains("jpg") { + Ok(FormatImageType::JPG) + } else { + Err(format!("No format recognized").into()) + }; + self.format = format?; + let max_depth_tile = hips_def.maxOrder; let tile_size = hips_def.tileSize; + self.tile_config = TileConfig::new(tile_size, &self.format, 0.0); + let texture_size = std::cmp::min(512, tile_size << max_depth_tile); let num_tile_per_side_texture = texture_size / tile_size; @@ -207,6 +239,9 @@ impl HiPSConfig { self.root_url = hips_def.url; self.min_cutout = hips_def.minCutout; self.max_cutout = hips_def.maxCutout; + crate::log(&format!("new hips config3 {:?}", self)); + + Ok(()) } #[inline] diff --git a/src/render/src/buffer/image.rs b/src/render/src/buffer/image.rs index b977d751..af811062 100644 --- a/src/render/src/buffer/image.rs +++ b/src/render/src/buffer/image.rs @@ -493,7 +493,7 @@ impl ReceiveImage for CompressedImageRequest { let width = self.image.width() as i32; let height = self.image.height() as i32; - let size =Vector2::new(width, height); + let size = Vector2::new(width, height); TileHTMLImage { size, image: self.image.clone() diff --git a/src/render/src/lib.rs b/src/render/src/lib.rs index 261a86c6..b0a4aa43 100644 --- a/src/render/src/lib.rs +++ b/src/render/src/lib.rs @@ -311,8 +311,8 @@ impl App { self.sphere.set_projection::

(&self.viewport, &self.shaders); } - fn set_image_survey(&mut self, hips_definition: HiPSDefinition) { - self.sphere.set_image_survey::

(hips_definition, &mut self.viewport, &mut self.task_executor); + fn set_image_survey(&mut self, hips_definition: HiPSDefinition) -> Result<(), JsValue> { + self.sphere.set_image_survey::

(hips_definition, &mut self.viewport, &mut self.task_executor) } fn add_catalog(&mut self, name: String, table: JsValue) { @@ -555,14 +555,14 @@ impl ProjectionType { }; } - pub fn set_image_survey(&mut self, app: &mut App, hips_definition: HiPSDefinition) { + pub fn set_image_survey(&mut self, app: &mut App, hips_definition: HiPSDefinition) -> Result<(), JsValue> { match self { ProjectionType::Aitoff => app.set_image_survey::(hips_definition), ProjectionType::MollWeide => app.set_image_survey::(hips_definition), ProjectionType::Ortho => app.set_image_survey::(hips_definition), ProjectionType::Arc => app.set_image_survey::(hips_definition), ProjectionType::Mercator => app.set_image_survey::(hips_definition), - }; + } } pub fn resize(&mut self, app: &mut App, width: f32, height: f32, enable_grid: bool) { @@ -756,8 +756,8 @@ impl WebClient { let gl = WebGl2Context::new(); let events = EventManager::new(); let shaders = ShaderManager::new(&gl, shaders).unwrap(); - let app = App::new(&gl, &events, shaders, resources)?; + //let appconfig = AppConfig::Ortho(app); let dt = DeltaTime::zero(); let enable_inertia = false; @@ -895,12 +895,12 @@ impl WebClient { /// Change HiPS #[wasm_bindgen(js_name = setImageSurvey)] pub fn set_image_survey(&mut self, - hips_definition: &JsValue, + hips_definition: JsValue, ) -> Result<(), JsValue> { let hips_definition: HiPSDefinition = hips_definition.into_serde().unwrap(); crate::log(&format!("hips_def222: {:?}", hips_definition)); - self.projection.set_image_survey(&mut self.app, hips_definition); + self.projection.set_image_survey(&mut self.app, hips_definition)?; Ok(()) } diff --git a/src/render/src/renderable/hips_sphere.rs b/src/render/src/renderable/hips_sphere.rs index 639cdf33..db54811a 100644 --- a/src/render/src/renderable/hips_sphere.rs +++ b/src/render/src/renderable/hips_sphere.rs @@ -237,6 +237,8 @@ use crate::{ use crate::TransferFunction; use crate::shaders::Colormap; use crate::HiPSDefinition; +use wasm_bindgen::JsValue; + impl HiPSSphere { pub fn new(gl: &WebGl2Context, viewport: &ViewPort, config: HiPSConfig, shaders: &ShaderManager) -> Self { let buffer = BufferTextures::new(gl, &config, viewport); @@ -259,14 +261,15 @@ impl HiPSSphere { gl, } } - - pub fn set_image_survey(&mut self, hips_definition: HiPSDefinition, viewport: &mut ViewPort, task_executor: &mut AladinTaskExecutor) { - self.config.set_HiPS_definition(hips_definition); + pub fn set_image_survey(&mut self, hips_definition: HiPSDefinition, viewport: &mut ViewPort, task_executor: &mut AladinTaskExecutor) -> Result<(), JsValue> { + self.config.set_HiPS_definition(hips_definition)?; // Tell the viewport the config has changed viewport.set_image_survey::

(&self.config); // Clear the buffer self.buffer.reset(&self.gl, &self.config, viewport, task_executor); + + Ok(()) } pub fn ask_for_tiles(&mut self, cells: &HashMap) {