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
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
// ! ! !
//
// IF THE PAGE IS STUCK AT THIS STAGE AND THE TEXT DOES NOT DISAPPEAR
// THAT MEANS THAT YOUR BROWSER IS NOT COMPATIBLE WITH THIS CODE YET
//
// PLEASE USE CHROME MEANWHILE
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
let φ = measure => {
// we could give stars around instead
// if(measure==undefined) measure = "Nothing"
// document.getElementById("selected").textContent = "[" + measure + "]"
};
let videoPlayerTime = {value:0};
let videoPlayerRate = 0.;
window.videoPlayer_play = () => {videoPlayerRate=1}
window.videoPlayer_play_faster = () => {videoPlayerRate+=3}
window.videoPlayer_pause = () => {videoPlayerRate=0}
window.videoPlayer_rewind = () => {videoPlayerRate=-1}
window.videoPlayer_rewind_faster = () => {videoPlayerRate-=3}
window.videoPlayer_stop = () => {videoPlayerRate=0;videoPlayerTime.value=0}
let videoPlayerGlobalTime = new Date();
let videoPlayerUpdate = () => {
let now = new Date();
let dt = (now - videoPlayerGlobalTime)/1000;
videoPlayerGlobalTime = now;
if(keyboardState['k']=='k') {
window.videoPlayer_pause();
} else if(keyboardState['l']=='l') {
if(keyboardState['Shift']=='Shift') {
window.videoPlayer_play_faster();
} else {
window.videoPlayer_play();
}
} else if(keyboardState['j']=='j') {
if(keyboardState['Shift']=='Shift') {
window.videoPlayer_rewind_faster();
} else {
window.videoPlayer_rewind();
}
} else if(keyboardState['h']=='h') {
if(keyboardState['Shift']=='Shift') {
videoPlayerRate=0;videoPlayerTime.value=60
} else {
window.videoPlayer_stop();
}
}
videoPlayerTime.value += dt*videoPlayerRate;
if(videoPlayerTime.value<0) {
videoPlayerTime.value=0;
videoPlayerRate=0;
}
// document.getElementById('thank-you').style.color='rgba(255,255,255,'+0.5+')'
if(videoPlayerRate!=0) {
renderplease();
}
window.requestAnimationFrame(videoPlayerUpdate)
}
videoPlayerUpdate();
// let renderAnimation = renderName => {
// let firstFrame = 33558
// let frameRate = 24*16; // [s⁻¹]
// let filmDuration = 2; // [s]
// let totalFrameCount = frameRate*filmDuration
// for(let frame=firstFrame; frame < totalFrameCount+firstFrame ;frame++) {
// videoPlayerTime.value = frame/frameRate;
// let frameIndex = "0000000000" + frame;
// frameIndex = frameIndex.substr(frameIndex.length-5);
// render2file( renderName + "-" + frameIndex + ".png");
// }
// // videoPlayerTime.value = 8;
// // render2file( "presentation-test.png");
// }
// setTimeout(() =>{renderAnimation("presentation")},100);
let splot;
{
let uniforms = {
videoPlayerTime: videoPlayerTime,
// colorTexture:colorTexture
};
let positions = [];
let velocities = [];
let angles = [];
let angleVelocities = [];
let angleGalactic = [];
let angleGalacticVelocities = [];
// 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*π // + Math.random()*0.1;
let δ = measure[index_dec] /180*π // + Math.random()*0.1;
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)/30000; // [pc]
let k = 4.74; // 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 _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 );
angleGalactic.push( b,l+π,ρ );
angleGalacticVelocities.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 angleGalacticBuffer = new THREE.Float32BufferAttribute( angleGalactic, 3 );
let angleGalacticVelocitiesBuffer = new THREE.Float32BufferAttribute( angleGalacticVelocities, 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( 'angleGalactic', angleGalacticBuffer );
geometry.addAttribute( 'angleGalacticVelocities', angleGalacticVelocitiesBuffer );
// geometry.addAttribute( 'size' , sizesBuffer );
let vertexShader = CGPUglsl + `
uniform float videoPlayerTime;
uniform mat4 slider_a_rot;
uniform vec2 slider_s_log;
uniform vec2 slider_b;
uniform vec2 slider_e;
uniform vec2 slider_i;
uniform vec2 slider_u_log;
uniform vec2 slider_w;
uniform vec2 slider_w_log;
uniform vec2 slider_q;
uniform vec2 slider_q_log;
// 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 vec3 angleGalactic;
attribute vec3 angleGalacticVelocity;
varying vec4 vColor;
float sigmoid(float x, float k) {
return 1./(1.+exp( -(x - k*k)/k ));
}
float sigmoid_lin(float x, float k) {
return x/(1.+exp( -(x - k*k)/k ));
}
void main() {
float ct = cos( time );
float st = sin( time );
mat4 rotationAnim = mat4(
ct,0,-st,0,
0,1,0,0,
st,0,ct,0,
0,0,0,1
);
vec4 mvPosition = rotationAnim*modelViewMatrix*vec4(position*5.,1.);
gl_Position = projectionMatrix * mvPosition;
gl_PointSize = 1. * slider_s_log.y;
vColor = vec4(1,1,1,1);
}
void main2() {
float t_keyframe1 = 2.;
float t_keyframe2 = 15.;
float t_keyframe3 = 20.;
float t_keyframe4 = 26.;
float t_keyframe5 = 28.;
float t_keyframe6 = 40.;
float t_keyframe7 = 55.;
float zoom = 1./(0.1+2.*sigmoid(videoPlayerTime-t_keyframe1,1.) + 10.*(
sigmoid(videoPlayerTime-t_keyframe3,0.5)
-sigmoid(videoPlayerTime-t_keyframe6,0.5)
+sigmoid(videoPlayerTime-t_keyframe7,0.5)
));
float hammer3dCtrl = 1. - clamp(slider_q.y,0.,1.)
-(1.
-sigmoid(videoPlayerTime-t_keyframe2,0.3)
+sigmoid(videoPlayerTime-t_keyframe6,0.3)
-sigmoid(videoPlayerTime-t_keyframe7,0.3)
);
float highlightCtrl = clamp(slider_w_log.y * (1.+5.*(
sigmoid(videoPlayerTime-t_keyframe4,0.5)
-sigmoid(videoPlayerTime-t_keyframe7,0.5)
)) ,1.,3.);
float highlightInvCtrl = 1./clamp(slider_w.y/2.+1.,1.,1.6);
float velocityMapCtrl = clamp(slider_e.x,0.,1.);
float rotationSpeed = 0.2;// 0.2;
float rotationSpeed2 = 0.2;// 0.2;
float lambda2_t = pi + rotationSpeed* sigmoid_lin(videoPlayerTime,1.5);
float ct = cos( lambda2_t );
float st = sin( lambda2_t );
mat4 rotationAnim = mat4(
ct,0,-st,0,
0,1,0,0,
st,0,ct,0,
0,0,0,1
);
// float ending_fun_angle = pi/8.*sin(sigmoid_lin(videoPlayerTime-t_keyframe7,1.5)*0.2);
float ending_fun_angle = (pi/8.) * sigmoid(videoPlayerTime-t_keyframe7,1.5);
ct = cos(ending_fun_angle);
st = sin(ending_fun_angle);
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;
// vec3 ending_fun_translate = vec3(.8,-.8,0.) * sigmoid(videoPlayerTime-t_keyframe7,1.);
vec3 ending_fun_translate = vec3(0,0,0);
mat4 solidTrans = mat4(1);
solidTrans = mat4(
1,0,0,0,
0,1,0,0,
0,0,1,0,
ending_fun_translate,1
);
mat4 zoomMat = mat4(zoom,0,0,0, 0,zoom,0,0, 0,0,zoom,0, 0,0,0,1);
vec4 pos = solidRot*vec4(position*5.,1.);
vec4 vel = vec4(velocity*5.,1.);
vec4 mvPosition = solidTrans*modelViewMatrix*zoomMat*rotationAnim * pos;
vec2 hammer = spheric2hammer(spheric_rotation(angleGalactic.yx + vec2(lambda2_t,0.), slider_a_rot));
vec4 mvHammerPosition = modelViewMatrix*zoomMat * vec4( hammer,angleGalactic.z,1.);
gl_Position = projectionMatrix * (
hammer3dCtrl*(mvPosition)
+ (1.-hammer3dCtrl)*(mvHammerPosition)
);
vec2 velocityMap2d = vec2(atan(angleVelocity.y*cos(angle.x),angleVelocity.x),angle.z);
vec4 velocityMap = projectionMatrix*modelViewMatrix*rotationAnim*vec4(velocityMap2d,0.,1.);
gl_Position = (1. - velocityMapCtrl)*gl_Position + velocityMapCtrl * velocityMap;
// float cluster = clamp( slider_u_log.y*abs(velocityMap2d.x + 2.05 )*abs(velocityMap2d.y -1. ) -.1,0.,1.);
float cluster = 1.-clamp( length(velocityMap2d - vec2(-2.05,1.))*5.,0.,1.);
// float cluster = 1.;
float size = 1.;
// size = 0.001*resolution.x;
// size = length(angleVelocity.xy);
// size = max(1. , size );
gl_PointSize = size * slider_s_log.y * highlightInvCtrl;
// orth scale
// gl_PointSize = gl_PointSize*pow(1.0 - gl_Position.z/gl_Position.w ,20000.);
gl_PointSize = gl_PointSize*(2. - 1000000.*gl_Position.z/gl_Position.w);
gl_PointSize = gl_PointSize*(.4+zoom);
float alpha = 1.;
float colorshift = 0.;
if (
// angleGalacticVelocity.y > slider_b.x &&
// (5.31 < angleGalacticVelocity.y && angleGalacticVelocity.y < 6.08)
(
(position.y > 0.3) &&
(position.y < 2.5) &&
(position.x > -0.0) &&
(position.x < 0.5) &&
(position.z > -1.0)&&
(position.z < 2.0)
)
) {
// float y2 = clamp(10.*abs(position.y-2.0),0.,10.);
float y1 = sin( clamp(abs(position.y-0.3)*2. ,0.,pi/2.));
float y2 = sin( clamp(abs(position.y-2.5)*1. ,0.,pi/2.));
float highlight = 1. + max(highlightCtrl-1.,0.)*clamp(y1*y2,0.,1.);
gl_PointSize = highlight * gl_PointSize;
colorshift = -.1*highlight*(
sigmoid(videoPlayerTime-t_keyframe4,0.5)
-sigmoid(videoPlayerTime-t_keyframe7,0.5)
);
// gl_PointSize = highlightCtrl*gl_PointSize;
// alpha=0.;
}
if (
(cluster !=0.) &&
(position.x < 0.0) &&
(position.x > -0.4)
) {
float highlight = 1. + max(highlightCtrl-1.,0.)*cluster;
gl_PointSize = highlight * gl_PointSize;
colorshift -= .1*highlight*(
sigmoid(videoPlayerTime-t_keyframe5,0.5)
-sigmoid(videoPlayerTime-t_keyframe7,0.5)
);
}
// vec3 s = vec3(.5+length(velocity)/100. + colorshift, 1. ,.8+clamp(-gl_Position.z*1000000.,0.,1.));
vec3 s = vec3(.5+clamp(length(velocity),0.,20.)/100. + colorshift, 1. ,1.);
// vec3 s = vec3(.5+length(angleGalacticVelocity.y)/2.,1.,1.0);
// vec3 s = vec3(length(angleGalacticVelocity.y)/10.,1.,1.0);
// vec3 s = vec3(atan(angleGalacticVelocity.x,angleGalacticVelocity.y/cos(angleGalactic.x)),1.,1.0);
vColor = vec4( hsv2rgb(s) ,alpha);
}`;
let fragmentShader = CGPUglsl + `
varying vec4 vColor;
void main() {
// float cluster = clamp( slider_u_log.y*abs(velocityMap2d.x + 2.05 )*abs(velocityMap2d.y -1. ) -.1,0.,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);