OrbitLens Devlog #3: Adding a dashboard + ISS 3d model implementation
I had two goals in my mind in this session. One was to add a
dashboard which displays some stats of the ISS and the other is to
replace the red dot with a 3d model of the ISS. Here is what and how I
implemented these stuff and the challenges i faced:
Change/Problem 1:
Before I even got started on the new stuff i wanted to add, i faced a
big problem. While testing the physics code and other stuff, my build
tool (Vite) was auto-refreshing the browser every time I hit save. This I
spammed CelesTrak’s public API with dozens of requests per minute. This
lead to me kinda getting IP blocked temporarily, at least that’s what i
think happend because it always returned an HTML error page instead of a
TLE string. My engine tried to calculate stuff with that empty TLE and
just crashed the engine
The fix:
It is important to know that a TLE is not like a live GPS broadcast
that gets transmitted every second. It’s literally like a mathematical
snapshot of a ton of stuff of the ISS like its position and its orbit
and NORAD only updates these TLEs like twice a day or sth. So I fixed
this api problem by making it such that the localStorage caches the TLE
once and uses it for the calculation for the next 12 hours and then
updates the TLE after that.
Change 2: Dashboard implementation
I implemented a dashboard that shows up on the top left of the screen and shows the following stuff abotu the ISS:
Longitude: the method i used to calculate this is in one of my
previous devlogs (i think my last one). But here is a quick summary:
To find coordinates I first calculated the Greenwich Mean Sidereal
Time (gmst), which gives me the exact rotational angle of the Earth at
that specific millisecond. I passed the ECI position (one of the
previosu devlogs) and gmst into satellite.eciToGeodetic(), which
projects the point onto the spinning globe in radians. I then multiplied
those values by 180/pi to convert the radians into standard degrees
latitude: same as longitude
-altitude: The eciToGeodetic() function also calculates the distance
from the satellite’s coordinates down to the mathematical surface of the
Earth (the WGS84 or the ‘World Geodetic System 1984’ ellipsoid which is
like a mathematical reference representation of the earth that is used
in calculatoin and stuff). It outputs this directly as height in
kilometers, which I then simply rounded to two dp.
-velocity: The propagate() function outputs the satellite’s speed
broken into X, Y, and Z axes (measured in km/s). To get a single speed, I
calculated the magnitude of that 3D vector using the 3D Pythagorean
theorem:
v = squareroot(x^2 + y^2 + z^2)
Change 3:
To implement a 3d model, i first needed that 3d image. I wanted the
highest quality NASA model available (Model D - IGOAL). I downloaded the
official .fbx, converted it to a .glb, and ended up with a 255mb file.
Which is really bad because shoving a 255mb file into a web browser
would just crash the entire thing. So i just ran that through a draco
compression and a texture compression (WebP 1024x1024) which brought the
size to about 18mb which was much better.
To render this, I used Three.js’s GLTFLoader with a dedicated Google WebAssembly DRACOLoader to decode the compressed math.
The next couple of changes were just to make it more realistic:
i changed the scale from 0.02 (where it was the size of a continent) to 0.001 (which made it a good size)
the direction the ISS faced was not accurate at all so I wanted to
rotate until its in the correct position. But because the animate() loop
was actively using math to point the model forward 60 times a second,
it kept overriding my manual rotation. So I wrapped the ISS in a
THREE.Group, rotated the mesh 90 degrees inside that container, and then
applied the math.
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.