sky: add Keplerian planets as colored larger points
This commit is contained in:
1 parent
dd36976712
commit
0d8a5f93d3
1 file changed
+108
-1
Vendored
+108
-1
@@ -5607,6 +5607,97 @@ function decodePlaneVerts() {
|
||||
// band (low-frequency by nature) stays a baked equirect texture.
|
||||
var skyTexCanvas = null, skyTexture = null, skyTexGl = null;
|
||||
var skyPts = null; // { prog, vbo, count, a0, a1, u: {...} }
|
||||
var planetVbo = null, planetCount = 0, planetNextT = 0;
|
||||
var DEG = Math.PI / 180;
|
||||
var PLANET_ELEMENTS = [
|
||||
{ name: 'Mercury', a: 0.387098, e: 0.205630, i: 7.005, N: 48.331, w: 29.124, M0: 177.453, P: 87.969,
|
||||
mag0: 1.0, color: [0.72, 0.68, 0.62], sizeCode: -8.0, bright: 0.75 },
|
||||
{ name: 'Venus', a: 0.723332, e: 0.006773, i: 3.395, N: 76.680, w: 54.884, M0: 50.115, P: 224.701,
|
||||
mag0: -4.0, color: [1.00, 0.95, 0.82], sizeCode: -10.0, bright: 1.15 },
|
||||
{ name: 'Mars', a: 1.523679, e: 0.093400, i: 1.850, N: 49.558, w: 286.502, M0: 355.453, P: 686.980,
|
||||
mag0: -1.5, color: [0.92, 0.45, 0.28], sizeCode: -8.0, bright: 0.85 },
|
||||
{ name: 'Jupiter', a: 5.20260, e: 0.048498, i: 1.303, N: 100.464, w: 273.867, M0: 20.020, P: 4332.589,
|
||||
mag0: -9.4, color: [0.95, 0.82, 0.62], sizeCode: -10.0, bright: 1.10 },
|
||||
{ name: 'Saturn', a: 9.55491, e: 0.055546, i: 2.489, N: 113.665, w: 339.392, M0: 317.020, P: 10759.22,
|
||||
mag0: -8.9, color: [0.96, 0.88, 0.68], sizeCode: -9.0, bright: 0.90 },
|
||||
{ name: 'Uranus', a: 19.21845, e: 0.047318, i: 0.773, N: 74.006, w: 96.999, M0: 142.239, P: 30685.4,
|
||||
mag0: -7.1, color: [0.55, 0.85, 0.92], sizeCode: -6.5, bright: 0.45 },
|
||||
{ name: 'Neptune', a: 30.11039, e: 0.008606, i: 1.770, N: 131.784, w: 273.187, M0: 256.228, P: 60189,
|
||||
mag0: -6.9, color: [0.35, 0.55, 0.95], sizeCode: -6.5, bright: 0.40 },
|
||||
{ name: 'Pluto', a: 39.482, e: 0.2488, i: 17.14, N: 110.30, w: 113.83, M0: 14.86, P: 90560,
|
||||
mag0: -1.0, color: [0.70, 0.62, 0.55], sizeCode: -5.5, bright: 0.18 }
|
||||
];
|
||||
var EARTH_ELEMENTS = { a: 1.000000, e: 0.016709, i: 0.000, N: 0.0, w: 102.947, M0: 100.464, P: 365.256 };
|
||||
|
||||
function planetKeplerE(Mdeg, e) {
|
||||
var M = ((Mdeg % 360) + 360) % 360;
|
||||
var Mr = M * DEG;
|
||||
var E = Mr;
|
||||
for (var k = 0; k < 8; k++) {
|
||||
E = E - (E - e * Math.sin(E) - Mr) / (1 - e * Math.cos(E));
|
||||
}
|
||||
return E;
|
||||
}
|
||||
function planetHeliocentric(p, d) {
|
||||
var n = 360 / p.P;
|
||||
var M = p.M0 + n * d;
|
||||
var E = planetKeplerE(M, p.e);
|
||||
var v = Math.atan2(Math.sqrt(1 - p.e * p.e) * Math.sin(E), Math.cos(E) - p.e);
|
||||
var r = p.a * (1 - p.e * Math.cos(E));
|
||||
var u = v + p.w * DEG;
|
||||
var N = p.N * DEG;
|
||||
var i = p.i * DEG;
|
||||
var x = r * (Math.cos(N) * Math.cos(u) - Math.sin(N) * Math.sin(u) * Math.cos(i));
|
||||
var y = r * (Math.sin(N) * Math.cos(u) * Math.cos(i) + Math.cos(N) * Math.sin(u));
|
||||
var z = r * Math.sin(u) * Math.sin(i);
|
||||
return [x, y, z];
|
||||
}
|
||||
function updatePlanetPoints(gl, date) {
|
||||
if (!gl || !date) return;
|
||||
var d = (date.getTime() - Date.UTC(2000, 0, 1, 12, 0, 0)) / 86400000;
|
||||
var earth = planetHeliocentric(EARTH_ELEMENTS, d);
|
||||
var data = new Float32Array(PLANET_ELEMENTS.length * 8);
|
||||
var di = 0, count = 0;
|
||||
var sLat = SKY_SIN_LAT, cLat = SKY_COS_LAT;
|
||||
var eps = 23.43928 * DEG;
|
||||
var ceps = Math.cos(eps), seps = Math.sin(eps);
|
||||
for (var pi = 0; pi < PLANET_ELEMENTS.length; pi++) {
|
||||
var p = PLANET_ELEMENTS[pi];
|
||||
var helio = planetHeliocentric(p, d);
|
||||
var gx = helio[0] - earth[0];
|
||||
var gy = helio[1] - earth[1];
|
||||
var gz = helio[2] - earth[2];
|
||||
var rGeo = Math.sqrt(gx * gx + gy * gy + gz * gz);
|
||||
var rSun = Math.sqrt(helio[0] * helio[0] + helio[1] * helio[1] + helio[2] * helio[2]);
|
||||
if (!(rGeo > 1e-6)) continue;
|
||||
var ex = gx;
|
||||
var ey = gy * ceps - gz * seps;
|
||||
var ez = gy * seps + gz * ceps;
|
||||
var el = Math.sqrt(ex * ex + ey * ey + ez * ez) || 1;
|
||||
var ra = Math.atan2(ey, ex);
|
||||
var dec = Math.asin(Math.max(-1, Math.min(1, ez / el)));
|
||||
var cd = Math.cos(dec), sd = Math.sin(dec);
|
||||
var cr = Math.cos(ra), sr = Math.sin(ra);
|
||||
var dx = cd * cr;
|
||||
var dy = sLat * sd + cLat * cd * sr;
|
||||
var dz = cLat * sd - sLat * cd * sr;
|
||||
// Approximate apparent magnitude from absolute magnitude and distances.
|
||||
// The clamp keeps inner planets from becoming absurdly bright because
|
||||
// this simplified model ignores phase angle.
|
||||
var mag = p.mag0 !== undefined ? p.mag0 : -1.0;
|
||||
mag = mag + 5 * Math.log10(Math.max(1e-6, rGeo * rSun));
|
||||
mag = Math.max(-5.0, Math.min(16.0, mag));
|
||||
var bright = p.bright * Math.max(0.12, Math.min(1.25, Math.pow(2.512, -mag * 0.35)));
|
||||
data[di++] = dx; data[di++] = dy; data[di++] = dz; data[di++] = p.sizeCode;
|
||||
data[di++] = p.color[0]; data[di++] = p.color[1]; data[di++] = p.color[2];
|
||||
data[di++] = bright;
|
||||
count++;
|
||||
}
|
||||
if (!planetVbo) planetVbo = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, planetVbo);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, data.subarray(0, di), gl.STREAM_DRAW);
|
||||
planetCount = count;
|
||||
}
|
||||
var STAR_BRIGHT = (((window.CONFIG && window.CONFIG.stars) || {}).brightness !== undefined)
|
||||
? Math.max(0.2, Number(window.CONFIG.stars.brightness)) : 1.6;
|
||||
// Star frame phase. The rotation is driven by real local sidereal time
|
||||
@@ -5655,7 +5746,13 @@ var SKYPTS_VERT = [
|
||||
// finite radius (inside the far plane): w=0 would put z_ndc just
|
||||
// outside [-1,1] and clip every single point away
|
||||
'gl_Position = uMVP * vec4(rp * 88.0, 1.0);',
|
||||
'gl_PointSize = clamp((7.2 - aSd.w) * 0.60 * uSizeScale, 1.4, 9.0);',
|
||||
'float baseSize;',
|
||||
'if (aSd.w < -5.0) {',
|
||||
'baseSize = (14.0 - aSd.w) * 0.72;',
|
||||
'} else {',
|
||||
'baseSize = (7.2 - aSd.w) * 0.60;',
|
||||
'}',
|
||||
'gl_PointSize = clamp(baseSize * uSizeScale, 1.4, 20.0);',
|
||||
'vC = aScol;',
|
||||
'}'
|
||||
].join('\n');
|
||||
@@ -6349,6 +6446,16 @@ window.clouds3dRender = function(target) {
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendFunc(gl.ONE, gl.ONE);
|
||||
gl.drawArrays(gl.POINTS, 0, skyPts.count);
|
||||
if (now - planetNextT > 30) {
|
||||
updatePlanetPoints(gl, window.__currentSceneDate || new Date());
|
||||
planetNextT = now;
|
||||
}
|
||||
if (planetCount && planetVbo) {
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, planetVbo);
|
||||
gl.vertexAttribPointer(skyPts.a0, 4, gl.FLOAT, false, 32, 0);
|
||||
gl.vertexAttribPointer(skyPts.a1, 4, gl.FLOAT, false, 32, 16);
|
||||
gl.drawArrays(gl.POINTS, 0, planetCount);
|
||||
}
|
||||
gl.disable(gl.BLEND);
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
gl.depthMask(true);
|
||||
|
||||
Reference in new issue
Block a user