A .NET tool that fetches Google Photorealistic 3D Tiles around a specified area and visualizes them non-persistently through Resonite Link. It provides subcommand-based entry points for single-shot streaming and resident interactive mode.
This README.md is the human-facing entry point. Current operational details and AI-oriented procedures are kept separately under docs/.
GitHub Releases are the canonical changelog for this project. We do not keep a separate CHANGELOG.md.
- To comply with Google Map Tiles API policy, streamed tiles must remain non-persistent.
- Resonite is a third-party renderer for Google Map Tiles API content. Using this tool does not waive Google Maps Platform attribution, logo, or provider-credit requirements.
- Keep the Google Maps attribution visible whenever streamed tiles are displayed.
- This integration publishes a compact text attribution surface through
World/ThreeDTilesLink.License; that line always includesGoogle Mapsand any currently required third-party providers. - Logo handling is not implemented by this tool. If your visible UI requires a Google Maps logo for compliance, handle that logo in your renderer or overlay layer and keep it separate from renderer branding.
- Keep third-party provider attributions visible in full alongside the Google Maps attribution while tiles are shown.
- Saving streamed content into the Resonite inventory is not supported.
SimpleAvatarProtectionis part of the Resonite-side mitigation for keeping the streamed content non-persistent.
.NET SDK 10.0+- Bundled GeographicLib geoid data (
egm96-5) - Google APIs required by feature
- 3D Tiles fetch (
stream,interactivetile streaming): Google Map Tiles APIGOOGLE_MAPS_API_KEYis required
- Free-text location search in Interactive (
World/ThreeDTilesLink.Search): Google Geocoding APIGOOGLE_MAPS_API_KEYis required
- 3D Tiles fetch (
- Advanced tile-source overrides are available when you need a non-default root or auth surface
TILE_SOURCE_ROOT_TILESET_URITILE_SOURCE_FILE_SCHEME_BASE_URITILE_SOURCE_API_KEYTILE_SOURCE_BEARER_TOKENTILE_SOURCE_INHERITED_QUERY_PARAMETERSSEARCH_API_KEY
- Enable Resonite Link in Resonite and confirm the destination port
At startup, the app automatically loads .env with parent-directory discovery and does not overwrite existing environment variables.
Use .env.example as the starting template when creating a local .env.
For Google tile streaming and Google Geocoding search, prefer the shared GOOGLE_MAPS_API_KEY.
Use the TILE_SOURCE_* and SEARCH_API_KEY overrides only when you need to separate tile fetch and search settings or point tile fetch at a different provider.
dotnet build ThreeDTilesLink.slnxdotnet test ThreeDTilesLink.slnx- Official releases are identified by
vX.Y.ZGit tags. - Pushing a
v*tag automatically creates a draft GitHub Release with autogenerated notes. - The GitHub Release body is the canonical changelog for the tagged version.
- Release assets are not attached; clone the repository or use GitHub's source archives instead.
- Review the draft in GitHub and publish it manually when it is ready.
Required Google API: Google Map Tiles API
dotnet run --project src/ThreeDTilesLink -- stream \
--latitude 35.65858 \
--longitude 139.745433 \
--range 400 \
--endpoint-port PLACEHOLDER--rangedefines the approximate square coverage half-width around the center point (X/Z local extent), not a strict spherical radius.- Large ranges prioritize coarse ancestor tiles first so the requested coverage is established before finer descendants arrive.
- Add
--dry-runto verify only the fetch and conversion path without sending anything to Resonite; in dry-run mode,--endpoint-portis optional. - Useful tuning flags include
--detail,--content-workers,--resonite-send-workers,--timeout,--log-level, and--measure-performance; use--helpfor the full set and defaults. - If
--endpoint-hostis omitted,localhostis used. - When running from WSL against a Windows-hosted Resonite session, prefer host-side execution such as
cmd.exe /c dotnet.exe run ...orpwsh.exe, because Linux-sidelocalhostdoes not reliably mean the Windows host. - For live verification, clear old
3DTilesLink Session ...roots before the case by runningtools/Invoke-ResoniteLinkCommand.ps1 cleanup-sessions. - Treat the standard Tokyo Tower live case as
--latitude 35.65858 --longitude 139.745433 --range 60without extra limiting arguments beyond the defaults. - If
--height-offsetis omitted,0is used. - The anchor height is sea level at the specified latitude/longitude, and
--height-offsetis applied relative to that anchor. - Run
dotnet run --project src/ThreeDTilesLink -- stream --helpfor units and defaults.
Required Google APIs by operation:
- Tile streaming from
Latitude/Longitude/Range: Google Map Tiles API - Free-text search from
Search: Google Geocoding API
At connection time, the app attaches session-root writable DynamicValueVariable<T> values for the Interactive input parameters:
LatitudeLongitudeRangeSearch
The Interactive loop reads those session-root values directly.
For convenience, the same input values are also exposed through fixed World/ThreeDTilesLink.* alias DynamicValueVariable<T> members driven through ValueCopy<T>.
Treat those aliases as convenience mirrors, not the primary control surface.
For the Interactive input parameters (Latitude / Longitude / Range / Search), ValueCopy.WriteBack is enabled so changes from World/ flow back into the session-side values.
For observation-only aliases, ValueCopy.WriteBack stays disabled so changes on the alias side do not overwrite the source values.
Those observation aliases stay fixed at:
World/ThreeDTilesLink.LicenseWorld/ThreeDTilesLink.AttributionRequirementsWorld/ThreeDTilesLink.ProgressWorld/ThreeDTilesLink.ProgressText
World/ThreeDTilesLink.License is the mandatory attribution surface for the currently visible Google tiles, not optional status text. World/ThreeDTilesLink.AttributionRequirements exposes the renderer-side compliance rule. If your renderer needs a Google Maps logo for compliance, implement that logo on the user side and keep it visually separate from Resonite or other third-party logos.
Value updates are handled with debounce/throttle; when a new run starts, the previous run task is canceled and retained tiles are reconciled for the latest selection.
During overlapping updates, retained tiles outside the latest Range are removed.
If Search is updated to a non-empty string, the app resolves it with the Google Geocoding API and writes the resulting coordinates back into Latitude / Longitude.
If the Interactive Range value is 0 or less, or if Latitude / Longitude are invalid, no streaming run is started. Existing streamed content can be removed from Resonite separately if needed.
If a run fails after the progress surface is available, World/ThreeDTilesLink.ProgressText shows the latest error.
When Range is large, the run first secures visible coverage with coarse ancestor tiles before refining toward smaller descendants.
dotnet run --project src/ThreeDTilesLink -- interactive \
--endpoint-port PLACEHOLDER \
--poll-interval 250 \
--debounce 800 \
--throttle 3000Run dotnet run --project src/ThreeDTilesLink -- interactive --help for units and defaults.
- If
--endpoint-hostis omitted,localhostis used. - When running from WSL against a Windows-hosted Resonite session, prefer host-side execution such as
cmd.exe /c dotnet.exe run ...orpwsh.exe, because Linux-sidelocalhostdoes not reliably mean the Windows host. - The anchor height is sea level at the current latitude/longitude, and
--height-offsetis applied relative to that anchor. - The Interactive input values are fixed session-root members; the observation aliases remain fixed under
World/ThreeDTilesLink.*. - Interactive mode always removes retained tiles that fall outside the latest
Rangeduring overlapping updates. - Useful tuning flags include
--poll-interval,--debounce,--throttle,--content-workers,--resonite-send-workers,--timeout,--log-level, and--measure-performance; use--helpfor the full set and defaults.
AGENTS.md: Minimal guide for coding agentsdocs/current-state.md: Current operational information and constraintsdocs/agent-procedures.md: Work procedures for AI agentsdocs/performance-3dtiles.md: Current performance notes for Google 3D Tiles fetch, decode, and traversaldocs/performance-resonitelink.md: Current performance notes for Resonite Link transport and ordering