Frames

Untitled

0
1import * as THREE from 'three';
2
3import { STAR_SHADER_VERTEX, STAR_SHADER_FRAGMENT } from './shaders';
4import { getFullUrl, getThreeJsTexture } from './util';
5import {
6 rad,
7 hoursToDeg,
8 sexagesimalToDecimalRa,
9 sexagesimalToDecimalDec,
10} from './Units';
11import {
12 sphericalToCartesian,
13 equatorialToEcliptic_Cartesian,
14 getObliquity,
15} from './Coordinates';
16
17const GALACTIC_CENTER_RA = sexagesimalToDecimalRa(17, 45, 40.04);
18const GALACTIC_CENTER_DEC = sexagesimalToDecimalDec(-29, 0, 28.1);
19
20/**
21 * Maps spectral class to star color
22 * @param temp {Number} Star temperature in Kelvin
23 * @return {Number} Color for star of given spectral class
24 */
25function getColorForStar(temp) {
26 if (temp >= 30000) return 0x92b5ff;
27 if (temp >= 10000) return 0xa2c0ff;
28 if (temp >= 7500) return 0xd5e0ff;
29 if (temp >= 6000) return 0xf9f5ff;
30 if (temp >= 5200) return 0xffede3;
31 if (temp >= 3700) return 0xffdab5;
32 if (temp >= 2400) return 0xffb56c;
33 return 0xffb56c;
34}
35
36/**
37 * Returns the pixel size of a star.
38 * @param mag {Number} Absolute magnitude of star
39 * @param minSize {Number} Pixel size of the smallest star
40 * @return {Number} Pixel size of star.
41 */
42function getSizeForStar(mag, minSize) {
43 if (mag < 2.0) return minSize * 4;
44 if (mag < 4.0) return minSize * 2;
45 if (mag < 6.0) return minSize;
46 return 1;
47}
48
49/**
50 * Builds a starry background that is accurate for the Earth's position in
51 * space.
52 */
53export class Stars {
54 /**
55 * @param {Number} options.minSize The size of the smallest star.
56 * Defaults to 0.75
57 */
58 constructor(options, contextOrSimulation) {
59 this._options = options;
60 this._id = `__stars_${new Date().getTime()}`;
61
62 // if (contextOrSimulation instanceOf Simulation) {
63 if (true) {
64 // User passed in Simulation
65 this._simulation = contextOrSimulation;
66 this._context = contextOrSimulation.getContext();
67 } else {
68 // User just passed in options
69 this._simulation = null;
70 this._context = contextOrSimulation;
71 }
72
73 this._stars = undefined;
74
75 this.init();
76 }
77
78 init() {
79 const dataUrl = getFullUrl(
80 '{{data}}/processed/bsc.json',
81 this._context.options.basePath,
82 );
83
84 fetch(dataUrl)
85 .then(resp => resp.json())
86 .then(library => {
87 const n = library.length;
88
89 const geometry = new THREE.BufferGeometry();
90
91 const positions = new Float32Array(n * 3);
92 const colors = new Float32Array(n * 3);
93 const sizes = new Float32Array(n);
94
95 geometry.addAttribute(
96 'position',
97 new THREE.BufferAttribute(positions, 3),
98 );
99 geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3));
100 geometry.addAttribute('size', new THREE.BufferAttribute(sizes, 1));
101
102 library.forEach((star, idx) => {
103 const [ra, dec, temp, mag] = star;
104
105 const raRad = rad(hoursToDeg(ra));
106 const decRad = rad(dec);
107
108 const cartesianSpherical = sphericalToCartesian(raRad, decRad, 1e9);
109 const pos = equatorialToEcliptic_Cartesian(
110 cartesianSpherical[0],
111 cartesianSpherical[1],
112 cartesianSpherical[2],
113 getObliquity(), // defaults to J2000 value
114 );
115
116 positions.set(pos, idx * 3);
117
118 const color = new THREE.Color(getColorForStar(temp));
119 colors.set(color.toArray(), idx * 3);
120
121 sizes[idx] = getSizeForStar(
122 mag,
123 this._options.minSize || 3.0 /* minSize */,
124 );
125 });
126
127 const material = new THREE.ShaderMaterial({
128 uniforms: {},
129 vertexColors: THREE.VertexColors,
130 vertexShader: STAR_SHADER_VERTEX,
131 fragmentShader: STAR_SHADER_FRAGMENT,
132
133 transparent: true,
134 });
135
136 this._stars = new THREE.Points(geometry, material);
137
138 if (this._simulation) {
139 this._simulation.addObject(this, true /* noUpdate */);
140 }
141 });
142 }
143
144 /**
145 * A list of THREE.js objects that are used to compose the skybox.
146 * @return {THREE.Object} Skybox mesh
147 */
148 get3jsObjects() {
149 return [this._stars];
150 }
151
152 /**
153 * Get the unique ID of this object.
154 * @return {String} id
155 */
156 getId() {
157 return this._id;
158 }
159}
160