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;
const mat4 j2k2gal = mat4(
-0.0548755604024359, -0.873437090247923, -0.4838350155267381, 0. ,
0.4941094279435681, -0.4448296299195045, 0.7469822444763707, 0. ,
-0.8676661489811610, -0.1980763734646737, 0.4559837762325372, 0. ,
0., 0., 0., 1.
);
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 main2() {
vec4 mvPosition =modelViewMatrix*vec4(position*5.,1.);
gl_Position = projectionMatrix * mvPosition;
gl_PointSize = 1. * slider_s_log.y;
vColor = vec4(1,1,1,1);
}
void main() {
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);
gl_PointSize = max(5.,gl_PointSize);
}`
let fragmentShader = CGPUglsl + `
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() {
// if (vColor.w == 0.) { discard; }
// float cluster = clamp( slider_u_log.y*abs(velocityMap2d.x + 2.05 )*abs(velocityMap2d.y -1. ) -.1,0.,1.);
vec2 p = gl_PointCoord - vec2(.5,.5);
float radius = length(p);
// if (radius - .5 > 0.) { discard; }
// gl_FragColor = vColor;
radius = sigmoid( - radius*2. + 0.5 , .1 );
gl_FragColor = vec4(vColor.xyz,radius);
}`
let pointProgram = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
// blending: THREE.NoBlending,
blending: THREE.AdditiveBlending,
depthTest: false
// transparent: true
})
console.log(THREE)
let points = new THREE.Points( geometry, pointProgram )
splot = new StellarPlot(data, undefined, φ, points)
}
output(splot)