MyGo 云音乐
用 Go 与 MyGo 写成的第三方网易云音乐桌面客户端。原生界面,没有 WebView;边下边播,无损与 Hi-Res,逐字歌词与「律动」,刘海播放器。
Translation pending
Walkable LoD1 city model on DGM terrain with sun/shadow simulation
Translation pending
MediaTypeScript · PythonGitHub @mdugueOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
A client-side, stylized 3D city walker: spawn into a pastel rendering of
Dresden built from Saxon open geodata and walk (or fly) through it. Buildings
come from LoD2 CityJSON, the ground from DGM1 elevation rasters,
surfaces (roads, water, meadow, …) from an ATKIS Basis-DLM land-cover
raster, and trees from DLM hedge/tree rows plus a DOM1-derived canopy. The
build turns it into an OGC 3D Tiles
tileset of glTF, which the browser streams with
3DTilesRendererJS and renders
with three.js (WebGPURenderer and TSL node
materials) — one route, no backend, no database, no accounts, nothing
persisted.Read the full README ↗A client-side, stylized 3D city walker: spawn into a pastel rendering of a
German city built from open geodata and walk (or fly) through it — Dresden
first, and any place whose Land publishes the data: Leipzig, Meißen, Grimma,
Hamburg, München, Berlin and Unna are configured. Buildings come from LoD2
CityGML/CityJSON, the ground from DGM1 elevation rasters, surfaces
(roads, water, meadow, …) from the ATKIS Basis-DLM (or OpenStreetMap where
the Land does not publish it openly), and trees from hedge/tree rows plus a
canopy derived from the surface model. The build turns it into an
OGC 3D Tiles tileset of glTF, which
the browser streams with
3DTilesRendererJS and renders
with three.js (WebGPURenderer and TSL node
materials) — a start page and one route per city (/dresden, /leipzig,
…), no backend, no database, no accounts; nothing persisted but what
the browser keeps for itself (the crash trail, the device's GPU safety
level — ADR 0046 —, a few preferences; the full list is on /datenschutz).
package.json packageManager)WebGPURenderer picks its WebGL2 backend; ?gpu=webgl2 forces it)pipeline/)bun install
bun dev # prepares public/data, then serves https://localhost:3000
The dev server speaks HTTPS only (WebGPU on a phone over the LAN needs a secure context); Next generates a self-signed certificate on the first run, so the browser asks once to accept it.
The data of seven cities is committed, so that is all: the start page at
/ lists Dresden, Grimma, Hamburg, Leipzig, Meißen, München and Unna,
and each viewer runs at its own route (/dresden, …). bun dev runs
scripts/prepare-sites.ts first, which runs scripts/prepare-data.ts for
every site whose data is ready; that bakes the site's data into a 3D Tiles
tileset in public/data/<site>/ — terrain meshes at two levels of detail
from the DGM GeoTIFFs, building meshes with a per-building attribute table
from the CityJSON — and publishes everything under content-hashed names with
a manifest.json (≈ 2 min cold for fifteen tiles, ≈ 1 s warm; the
bake cache lives in .cache/). The index of the built sites,
public/data/sites.json, is what the start page lists.
Add ?scene=lite (/dresden?scene=lite) to stream the spawn tile alone with a small shadow map —
that is what the headless e2e suite uses; it is not how the scene is meant to
look.
bun run fetch leipzig # downloads the site's data (once; minutes to
# an hour — statewide packages are GBs)
bun run bake leipzig # derives land cover, trees, lamps, … (minutes)
bun run site leipzig # where the site stands, tile by tile
bun dev # or: bun run build — now also /leipzig
The site is the first argument of every script (leipzig, meissen,
grimma, hamburg, muenchen, berlin, unna, dresden); a wrong or
missing one stops with the list. The build serves every site whose data is
ready, each under its own route, and the start page gains a card for it
(bun scripts/prepare-sites.ts leipzig unna prepares only those). Each site
is one file in
sites/ — its tiles (2 km cells, the first is the spawn),
curated viewpoints, and the data provider it draws on
(sites/providers.ts: CRS, licence and credit, which
products are open). bun run site --all lists every site and how much of it
is on disk. Adding a place in a covered Land is one file plus one line in
sites/index.ts; see portability.
Deploying more cities needs no configuration: one deployment serves
every site whose data/<id>/ is present where it builds, at /<id>. A host
that builds from git sees only what is committed — the seven cities above
(.gitignore un-ignores each by name); un-ignore a new site's folder once
you decide to ship it — it is roughly 20–90 MB per site, plain git, no LFS (ADR 0037).
Crash and performance reports are optional: set
NEXT_PUBLIC_SENTRY_DSN (a Sentry project's DSN, or any tracker that takes
Sentry envelopes) in the deploy's environment and rebuild. The viewer then
reports pages the phone killed (from the next load), the errors it catches,
each page's frame rate and memory and a session per page (crash-free rate
per release) — no SDK, no position, no cookie, through the site's own
origin (ADR 0043).
With SENTRY_AUTH_TOKEN (an organisation token), SENTRY_ORG and
SENTRY_PROJECT there as well, the build creates its release,
bridge@<commit>, with its commit and deploy. Without a DSN, nothing is
sent.
Impressum and privacy policy (/impressum, /datenschutz, German)
are MDX pages, app/(legal)/*/page.mdx (@next/mdx), and name this
deployment's operator, host (Vercel) and tracker (Sentry, EU region) —
a deployment of your own edits them. Visitors turn the reports off on
the privacy page (ADR 0045).
provider portals ── bun run fetch <site> ──→ data/_raw/<provider>/ (downloads, gitignored)
└─→ data/<site>/dgm, cityjson (build sources)
data/_raw + data/<site> ── bun run bake <site> ──→ data/<site>/dlm, dop (derived, small)
data/<site>/ ── scripts/prepare-sites.ts (bun dev/build) ──→ public/data/<site>/ (3D Tiles)
└─→ public/data/sites.json (the index)
The fetch step is one adapter per Land in pipeline/bake/providers/
(Saxony, NRW, Bavaria, Hamburg, Berlin): it mosaics and clips each
provider's grid to our 2 km tiles, writes the DGM compactly and converts the
LoD2 CityGML to CityJSON with its own converter (no Java, no extra tools).
The bulky downloads — surface model, orthophotos, the statewide Basis-DLM,
the OSM extract — are kept per provider, so sites in one Land share them;
a tile's DGM and LoD2 go straight into data/<site>/.
Tile id scheme: <UTM zone><easting km>_<northing km>_2_<provider> — Dresden
spawns on 33412_5656_2_sn, spanning 412000–414000 E / 5656000–5658000 N in
EPSG:25833 (the provider sets the CRS: EPSG:25833 for Saxony and Berlin,
25832 for Hamburg, Bavaria and NRW). The viewer streams every tile of the site around the camera —
detailed near, coarse far, unloaded when out of view — and walking, collision
and demolish work on every loaded tile.
Neither the DGM1 GeoTIFF nor the CityJSON is served. prepare-data.ts
turns the DGM into terrain meshes at two levels — the fine one an
error-bounded TIN of the native 1 m DGM (±0.15 m) with retaining walls
snapped to the measured step, the coarse one the DGM resampled to 512² with
the walls burned in as breaklines — and runs the CityJSON parser once at build
time; both are written as standard glTF (meshopt-compressed, quantised,
buildings with an EXT_mesh_features / EXT_structural_metadata table) into
a tileset (lib/city/tileset.ts). Every /data file
is published under a content-hashed name and cached as immutable; each
site's manifest.json maps the logical names and, with sites.json, is
what revalidates.
Provenance. Each provider's licence and credit line is in
sites/providers.ts and shows in the HUD footer. For
Dresden: the Saxon open-geodata portal of
GeoSN (Datenlizenz Deutschland – Namensnennung 2.0, "Quelle: GeoSN,
dl-de/by-2-0") plus OpenStreetMap for street lamps, retaining walls, station
platforms and bridge structure (ODbL, "© OpenStreetMap contributors"). Every
dataset — download route, strengths and weaknesses, the editions in use — is
described in the guide Where the data comes from
(deutsch).
Desktop:
| Input | Action |
|---|---|
| Drag | Look around |
W A S D | Move (Shift sprints) |
F | Toggle walk / fly (an animated take-off / landing) |
Space / Shift | Up / down (fly mode) |
| Scroll | Move forward / back |
Alt + scroll | Zoom (field of view) |
| Double-click the ground | Glide there |
| Click the minimap | Glide there |
R | Demolish the building under the crosshair |
| "Immersive mode" | Pointer lock (Esc exits) |
Touch: drag to look, joystick to walk, pinch to move forward / back, double-tap the ground to glide there, and the button in the corner opens the scene settings.
A React shell owns the HUD; three.js owns the canvas.
app/_components/city-walk.tsx mounts
createCityWalkApp (create-app.ts), which
builds the scene imperatively and returns a handle of setters — every HUD
slider calls one. Pure, three-free, unit-tested math lives in
lib/city/; the renderer, the TSL node materials and the
post pipeline live in app/_components/.
Coordinate frames matter here. Source data is ETRS89/UTM, Z-up
(EPSG:25833 for Saxony and Berlin, 25832 for Hamburg, Bavaria and NRW); a parent
world group is rotated −90° about X so data-Z (elevation) becomes scene-Y
(up), giving x = easting − cx, z = −(northing − cy), y = elevation, with
(cx, cy) the shared recenter offset (lib/city/recenter.ts,
lib/city/ground-clamp.ts). The sun goes suncalc →
ENU → world in lib/city/sun.ts — note suncalc 2 reports
degrees with a north-based azimuth (1.x used radians measured from south).
Two design decisions worth knowing: demolish filters the building's
triangles out of its tile's index buffer and rebuilds the tile's BVH — there
is no CityJSON in the browser to re-parse (city-layer.ts), and
cityjson-threejs-loader is patched via patches/ — read the
patch header before bumping it. The reasoning behind these and the other
load-bearing choices is recorded in docs/adr.
bun run verify # lint + typecheck + unit tests — run this before pushing
bun run build
bun run test:e2e # Playwright, against a production build
bun run fix # oxfmt + oxlint --fix
bun run shots # real-GPU screenshot plates from shots/*.json (headed)
bun run bake dresden # offline bakes (needs uv): raw downloads → data/
bun run test:pipeline # pytest + ruff for pipeline/
Unit tests are bun test files colocated with the code they cover (lib/,
app/_components/ and scripts/); the bakes have their own pytest suite in
pipeline/tests/. The e2e specs drive the viewer through the window.__poc
hook (poc-debug.ts), which dev builds expose
automatically and production builds only with NEXT_PUBLIC_POC_DEBUG=1;
changing that hook means updating e2e/.
The code is licensed under the Apache License 2.0. The geodata
are not: data/ and everything built from it stay under the licences of
their sources — the survey offices' open-data licences (dl-de/by-2-0,
dl-de/zero-2-0, CC BY 4.0), the ODbL for everything derived from
OpenStreetMap (share-alike: a database derived from it stays under the
ODbL), CC BY 4.0 for the timetable. NOTICE has the credits; the
guide lists every source with its licence
(Licences and credits).