SHIFT + SCROLL : camera pan
CTRL + SCROLL : camera zoom
ALT + SCROLL : camera rotate
S + SCROLL : scale point size
A + SCROLL : spherical coord rotation
1,2,3 : view face,right,top

forceAnimation(true); let φ = measure => { // we could give stars around instead // if(measure==undefined) measure = "Nothing" // document.getElementById("selected").textContent = "[" + measure + "]" }; let splot; { let uniforms = { // colorTexture:colorTexture }; let positions = []; let velocities = []; let angles = []; let angleVelocities = []; // let sizes = []; // let indexInArray = []; data.map( (measure,index) => { let phot_g = measure[index_phot_g_mean_mag]; let phot_bp = measure[index_phot_bp_mean_mag]; let phot_rp = measure[index_phot_rp_mean_mag]; //////////////////////////////////////////////////////////////////////////// // ρφθ position let α = measure[index_ra] /180*π; let δ = measure[index_dec] /180*π; // let [l,b] = CooConversion.J20002Galactic([α*180/π,δ*180/π]); // b*=π/180; // l*=-π/180; let M = 0.6; // rough estimation let ρ = Math.pow(10,(phot_g - M + 5)/5); // [pc] //30000; let k = 4.74 * 1000; // VT [km s-1] = 4.74 1000 mu [ pc mas yr⁻¹] let μαstar = measure[index_pmra]; // [mas.yr⁻¹] let μα = μαstar/cos(δ); let μδ = measure[index_pmdec] let μρ = measure[index_radial_velocity]/k||0; // [ pc mas yr⁻¹] default amplitude to 0 if absent from DB // ! TODO : this transform is not the right one (it's unused here but should be fixed) : // let [μl,μb] = CooConversion.J20002Galactic([μα*180/π,μδ*180/π]); // let [μφ,μb] = CooConversion.J20002Galactic([μαstar*180/π,μδ*180/π]); // μb*=π/180; // μl*=π/180; // μb=1; // μb=0; // μφ=0; // μρ=0; //////////////////////////////////////////////////////////////////////////// // xyz position // let x = ρ*cos(b)*cos(l); // let y = ρ*cos(b)*sin(l); // let z = ρ*sin(b); // let vx = μρ*cos(b)*cos(l) - ρ*μb*sin(b)*cos(l) - ρ*μl*cos(b)*sin(l); // let vy = μρ*cos(b)*cos(l) - ρ*μb*sin(b)*sin(l) + ρ*μl*cos(b)*cos(l); // let vz = μρ*sin(b) + ρ*μb*cos(b); let x = ρ*cos(δ)*cos(α); // [pc] let y = ρ*cos(δ)*sin(α); // [pc] let z = ρ*sin(δ); // [pc] let mas_2_rad = 2*π/ (360 * 3600 * 1000) ; let Giga = 10**9; let vx = (/*μρ*cos(δ)*cos(α)*/ - ρ*μδ*sin(δ)*cos(α) - ρ*μα*cos(δ)*sin(α)) * (mas_2_rad * (Giga)); // [pc Gyr⁻¹] let vy = (/*μρ*cos(δ)*cos(α)*/ - ρ*μδ*sin(δ)*sin(α) + ρ*μα*cos(δ)*cos(α)) * (mas_2_rad * (Giga)); // [pc Gyr⁻¹] let vz = (/*μρ*sin(δ) */ + ρ*μδ*cos(δ) ) * (mas_2_rad * (Giga)); // [pc Gyr⁻¹] let pos_norm = sqrt(x*x + y*y + z*z); let x_dir = x / pos_norm; let y_dir = y / pos_norm; let z_dir = z / pos_norm; // remove sun motion // let vx_sun = 10; // let vy_sun = 20; // let vz_sun = 30; // let proj_v_dir = vx_sun*x_dir + vy_sun*y_dir + vz_sun*z_dir; // vx -= vx_sun - proj_v_dir *x_dir; // vy -= vy_sun - proj_v_dir *y_dir; // vz -= vz_sun - proj_v_dir *z_dir; //////////////////////////////////////////////////////////////////////////// // let _bp = Math.pow ( 10, -(phot_bp-bp_min)/(bp_max-bp_min) ); // let _rp = Math.pow ( 10, -(phot_rp-rp_min)/(rp_max-rp_min) ); // let _g = Math.pow ( 10, -(phot_g-g_min)/(g_max-g_min) ); // let _g = _bp+_rp; // let vα = μαstar*ρ; // let vδ = μδ *ρ; // let v = Math.sqrt(vx*vx + vy*vy) // let μAngle = atan2(vy,vx); // let ang = Math.atan2(vy,vx); // let r = Math.cos(ang)*.5 + .5; // let g = Math.sin(2*ang)*.5 + .5; // let b = 1; // picking // let indexC = id2rgba(index); // indexInArray.push( indexC[0]/255, indexC[1]/255, indexC[2]/255, indexC[3]/255 ); // actual plot positions.push( x,y,z ); velocities.push( vx, vy, vz ); // positions.push( y,z,x ); // velocities.push( vy, vz, vx ); // angles.push( b,l+π,ρ ); // angleVelocities.push( μb,μl,μρ); angles.push( δ,α,ρ ); angleVelocities.push( μδ,μα,μρ); // sizes.push( obs.size ); }); let positionsBuffer = new THREE.Float32BufferAttribute( positions, 3 ); let anglesBuffer = new THREE.Float32BufferAttribute( angles, 3 ); let velocitiesBuffer = new THREE.Float32BufferAttribute( velocities, 3 ); let angleVelocitiesBuffer = new THREE.Float32BufferAttribute( angleVelocities, 3 ); // let indexBuffer = new THREE.Float32BufferAttribute( indexInArray, 4 ); // let sizesBuffer = new THREE.Float32BufferAttribute( sizes, 1 ); let geometry = new THREE.BufferGeometry(); geometry.addAttribute( 'position', positionsBuffer ); geometry.addAttribute( 'velocity' , velocitiesBuffer ); geometry.addAttribute( 'angle', anglesBuffer ); geometry.addAttribute( 'angleVelocity', angleVelocitiesBuffer ); // geometry.addAttribute( 'size' , sizesBuffer ); let vertexShader = CGPUglsl + ` uniform mat4 slider_a_rot; uniform vec2 slider_s_log; uniform vec2 slider_b; uniform vec2 slider_q; uniform vec2 slider_q_log; uniform vec2 slider_w; uniform vec2 slider_u; uniform vec2 slider_u_log; uniform vec2 slider_w_log; uniform vec2 slider_e; uniform vec2 slider_r; // uniform sampler2D colorTexture; // uniform bool key_k; // uniform vec2 slider_c; // uniform vec2 slider_v_log; // uniform mat4 slider_l_rot; // uniform vec2 slider_o; // uniform vec2 slider_p; attribute vec3 velocity; attribute vec3 angle; attribute vec3 angleVelocity; // attribute vec4 color; // attribute vec4 velocity; // attribute float size; // varying vec4 vColorInput; varying vec4 vIndexColor; varying vec4 vColor; const mat3 j2k2gal = mat3( -0.0548755604024359, -0.873437090247923, -0.4838350155267381, 0.4941094279435681, -0.4448296299195045, 0.7469822444763707, -0.8676661489811610, -0.1980763734646737, 0.4559837762325372 ); void main() { float hammer3dCtrl = clamp(slider_q.y,0.,1.); float velocityCtrl = clamp(slider_q_log.x,0.,10.); float sunMoRemCtrl = clamp(slider_w.x,0.,1.); float ct = cos(pi/2.); float st = sin(pi/2.); mat4 solidRot = mat4(1); // solidRot = mat4( // 1,0,0,0, // 0,ct,-st,0, // 0,st,ct,0, // 0,0,0,1 // ); // solidRot = mat4( // ct,0,-st,0, // 0,1,0,0, // st,0,ct,0, // 0,0,0,1 // )* solidRot; vec4 pos = solidRot*vec4(inverse(j2k2gal)*position,1.); vec3 dir = pos.xyz/length(pos.xyz); // vec3 sun_v = vec3(11.1,12.24,7.25)*(3.24078e-14/3.17098e-8*10e9); // [pc Gyr⁻¹] vec3 sun_v = vec3(10.*slider_e,10.*slider_r.x)*(3.24078e-14/3.17098e-8*10e9); // [pc Gyr⁻¹] vec3 parasite_v = sun_v - dot(sun_v,dir)*dir; // vec3 v = velocity; // vec3 v = j2k2gal*parasite_v; // vec3 v = velocity + sunMoRemCtrl*j2k2gal*parasite_v; vec3 v = velocity + j2k2gal*parasite_v; vec4 vel = solidRot*vec4(inverse(j2k2gal)*v,1.); pos = vec4(pos.xyz/30000.,1.); vel = vec4(vel.xyz/30000.,1.); // vec4 pos = vec4(position/10000.,1.); // vec4 vel = vec4(velocity/10000.,1.); vec4 mvPosition = modelViewMatrix * pos; vec2 hammer = spheric2hammer(spheric_rotation(angle.yx, slider_a_rot)); vec4 mvHammerPosition = modelViewMatrix * vec4( hammer,angle.z/30000.,1.); vec2 anglePerturbation = angle.yx + velocityCtrl*0.002*cos(5.*time)*angleVelocity.yx; vec2 hammerVelocity = spheric2hammer(spheric_rotation( anglePerturbation, slider_a_rot)); vec4 mvHammerVelocityPosition = modelViewMatrix * vec4( hammerVelocity,angle.z/30000.,1.); vec4 mvVelocity = modelViewMatrix * ( vec4(pos.xyz + velocityCtrl*.0025*cos(5.*time)*vel.xyz,1.) ); gl_Position = projectionMatrix * ( (1.-hammer3dCtrl)*mvVelocity + hammer3dCtrl*mvHammerVelocityPosition ); // // do nothing float size = 1.; size = length(vel.xy)/10000.; size = clamp(size,1.,20.); gl_PointSize = size * slider_s_log.y; float alpha = 1.; if ( abs(pos.z+slider_u.x/10.) > slider_u_log.y*10. ) { // gl_PointSize = gl_PointSize/200.; // gl_PointSize = 0.; alpha = 0.; } // orth scale // gl_PointSize = gl_PointSize*pow(1.0 - gl_Position.z/gl_Position.w ,2.); float colorshift = 0.; vec3 s = vec3(.5+length(vel)/30. + colorshift,1.,1.0); // vec3 s = vec3(-0.1 + slider_e.x+length(pos)/2. + colorshift,1.,1.0); // vec3 s = vec3(.5+length(angleVelocity.y)/2.,1.,1.0); // vec3 s = vec3(length(angleVelocity.y)/10.,1.,1.0); // vec3 s = vec3(atan(angleVelocity.x,angleVelocity.y/cos(angle.x)),1.,1.0); vColor = vec4( hsv2rgb(s) ,alpha); }`; let fragmentShader = CGPUglsl + ` varying vec4 vColor; void main() { // gl_FragColor = vec4( 1.,1.,1.,1. ); // gl_FragColor = vec4( vVelocity,1. ); if (vColor.w == 0.) { discard; } gl_FragColor = vColor; }`; let material = new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader: vertexShader, fragmentShader: fragmentShader, blending: THREE.NoBlending, // transparent: true }); let points = new THREE.Points( geometry, material ) splot = new StellarPlot(data, undefined, φ, points); } output(splot);