entangled-worlds-orbiters-shared 3.1.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/star/framing.d.ts +17 -6
- package/dist/star/framing.js +16 -52
- package/dist/star/index.d.ts +1 -1
- package/dist/star/index.js +1 -1
- package/dist/star/layout.js +1 -2
- package/dist/star/params.js +3 -2
- package/dist/types/config/env.d.ts +12 -0
- package/dist/types/config/index.d.ts +2 -0
- package/dist/types/config/textureConfig.d.ts +121 -0
- package/dist/types/core/index.d.ts +2 -0
- package/dist/types/core/lightFresnel.d.ts +5 -0
- package/dist/types/core/lights.d.ts +58 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/loaders/bodyTextureLoader.d.ts +12 -0
- package/dist/types/loaders/cubeMapLoader.d.ts +70 -0
- package/dist/types/loaders/glbLoader.d.ts +24 -0
- package/dist/types/loaders/index.d.ts +5 -0
- package/dist/types/loaders/ktx2.d.ts +16 -0
- package/dist/types/moons/index.d.ts +2 -0
- package/dist/types/moons/moonsGeneration.d.ts +72 -0
- package/dist/types/moons/moonsManager.d.ts +27 -0
- package/dist/types/render/frameBudget.d.ts +29 -0
- package/dist/types/render/index.d.ts +2 -0
- package/dist/types/render/viewportCompositor.d.ts +58 -0
- package/dist/types/utils/dispose.d.ts +2 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/materials.d.ts +2 -0
- package/dist/types/world/cloudShell.d.ts +25 -0
- package/dist/types/world/index.d.ts +6 -0
- package/dist/types/world/worldGLB.d.ts +20 -0
- package/dist/types/world/worldManager.d.ts +63 -0
- package/dist/types/world/worldNormal.d.ts +43 -0
- package/dist/types/world/worldTexture.d.ts +80 -0
- package/package.json +35 -10
- package/src/config/env.js +8 -0
- package/src/core/lights.js +12 -0
- package/src/loaders/bodyTextureLoader.js +7 -0
- package/src/loaders/cubeMapLoader.js +27 -0
- package/src/loaders/glbLoader.js +7 -1
- package/src/loaders/index.js +3 -1
- package/src/moons/moonsGeneration.js +32 -2
- package/src/moons/moonsManager.js +1 -1
- package/src/star/framing.ts +17 -55
- package/src/star/index.ts +1 -1
- package/src/star/layout.ts +1 -2
- package/src/star/params.ts +3 -2
- package/src/world/cloudShell.js +13 -0
- package/src/world/index.js +3 -1
- package/src/world/worldGLB.js +12 -1
- package/src/world/worldManager.js +32 -1
- package/src/world/worldNormal.js +19 -0
- package/src/world/worldTexture.js +41 -0
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ import * as EntangledWorlds from 'entangled-worlds-orbiters-shared';
|
|
|
76
76
|
- `DEFAULT_STAR_PARAMS`, `normalizeStarParams` - Author params (temperature, radius, luminosity, activity, multiplicity, separation, seed, placement) + validator for stored params
|
|
77
77
|
- `starParamsFromStellarData` - Catalogue host-star data (Teff, radius, mass, luminosity, spectral type, star count or a "(AB)b" name suffix) → params
|
|
78
78
|
- `blackbodyColor`, `spectralClass`, `starLayout`, `starPositions` - Pure colour / layout / orbit helpers
|
|
79
|
-
- `getFocus` (on `createStar` / `StarManager`), `framingDistance`, `defaultStarPlacement` - Camera focus on the system barycentre and
|
|
79
|
+
- `getFocus` (on `createStar` / `StarManager`), `framingDistance`, `defaultStarPlacement` - Camera focus on the system barycentre and the default placement (over the camera's shoulder, so worlds open on their day side)
|
|
80
80
|
- The star lights the scene: `StarManager` key + camera-side fill lights, `setLighting`, `lightingFromLegacy`, `DEFAULT_AMBIENT` (pair with `setHemisphereEnabled(scene, false)` from `./core`; moons `emissiveLift`, GLB `emissiveIntensity` for night sides)
|
|
81
81
|
- Real binaries (close pair from component masses, a distant companion for wide pairs) and an optional debris disc; `mainSequenceTemperature` / `Radius` / `Luminosity` helpers
|
|
82
82
|
- Perf + look harness: `npm run bench:star` (see `bench/star/results/REPORT.md`)
|
package/dist/star/framing.d.ts
CHANGED
|
@@ -19,13 +19,24 @@ export interface StarPlacementInput {
|
|
|
19
19
|
export interface StarPlacement {
|
|
20
20
|
azimuth: number;
|
|
21
21
|
elevation: number;
|
|
22
|
-
/**
|
|
22
|
+
/** Always true (kept for older hosts): the spot is behind any camera closer than ~0.79 × the star's distance (≥ 15.8 units). */
|
|
23
23
|
fits: boolean;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
26
|
+
* The opening light: the star over the camera's right shoulder (behind it, a little up and to the
|
|
27
|
+
* right), so the planet opens on its day side — about 90% of the face the camera sees is lit, the
|
|
28
|
+
* night edge on the left — and the star itself shows when the viewer orbits round. 145° / 15° is
|
|
29
|
+
* ~38° off the view axis. It is `DEFAULT_STAR_PARAMS`' direction, so a host with no camera gets it too.
|
|
30
30
|
*/
|
|
31
|
-
export declare
|
|
31
|
+
export declare const OVER_THE_SHOULDER: {
|
|
32
|
+
readonly azimuth: number;
|
|
33
|
+
readonly elevation: number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Azimuth / elevation of the default star for a camera on +Z looking at the origin: over the
|
|
37
|
+
* camera's shoulder (`OVER_THE_SHOULDER`), so the world opens lit. The star sits ≥ 0.79 × its
|
|
38
|
+
* distance (≥ 15.8 units) out on +Z, behind any host camera, so the frame never changes it. Hosts
|
|
39
|
+
* use it only when the author has not set azimuth/elevation; `DEFAULT_STAR_PARAMS` stays the
|
|
40
|
+
* host-agnostic fallback.
|
|
41
|
+
*/
|
|
42
|
+
export declare function defaultStarPlacement(_input?: StarPlacementInput): StarPlacement;
|
package/dist/star/framing.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Camera framing helpers (pure, no three): how far a camera must sit to fit a focus sphere, and a
|
|
2
|
-
//
|
|
3
|
-
import {
|
|
4
|
-
import { DEFAULT_STAR_PARAMS, STAR_PARAM_RANGES } from './params.js';
|
|
2
|
+
// default placement for the star that lights the planet's side facing the camera.
|
|
3
|
+
import { DEFAULT_STAR_PARAMS } from './params.js';
|
|
5
4
|
const DEG = Math.PI / 180;
|
|
6
5
|
/**
|
|
7
6
|
* Camera distance (from the sphere's centre) at which a sphere of `radius` fits inside both the
|
|
@@ -15,54 +14,19 @@ export function framingDistance(radius, fovDeg, aspect, margin = 1.15) {
|
|
|
15
14
|
return r / Math.sin(Math.min(halfV, halfH));
|
|
16
15
|
}
|
|
17
16
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
17
|
+
* The opening light: the star over the camera's right shoulder (behind it, a little up and to the
|
|
18
|
+
* right), so the planet opens on its day side — about 90% of the face the camera sees is lit, the
|
|
19
|
+
* night edge on the left — and the star itself shows when the viewer orbits round. 145° / 15° is
|
|
20
|
+
* ~38° off the view axis. It is `DEFAULT_STAR_PARAMS`' direction, so a host with no camera gets it too.
|
|
22
21
|
*/
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const tanH = tanV * aspect;
|
|
34
|
-
const planetTan = cd > pr ? pr / Math.sqrt(cd * cd - pr * pr) : Infinity;
|
|
35
|
-
const starTan = (starRadius * FOCUS_GLOW_RADII) / Math.sqrt(D * D + cd * cd);
|
|
36
|
-
const rho = planetTan + starTan * 1.35; // centre distance from the view axis: disc + glow clear the planet
|
|
37
|
-
const maxX = tanH * 0.97 - starTan * 0.5; // centre in frame, disc mostly in frame
|
|
38
|
-
const maxY = tanV * 0.97 - starTan * 0.5;
|
|
39
|
-
let x = 0;
|
|
40
|
-
let y = Number.isFinite(rho) ? rho : maxY;
|
|
41
|
-
let fits = false;
|
|
42
|
-
for (let phiDeg = 30; phiDeg <= 90; phiDeg += 2) {
|
|
43
|
-
const px = rho * Math.cos(phiDeg * DEG);
|
|
44
|
-
const py = rho * Math.sin(phiDeg * DEG);
|
|
45
|
-
if (px <= maxX && py <= maxY) {
|
|
46
|
-
x = px;
|
|
47
|
-
y = py;
|
|
48
|
-
fits = true;
|
|
49
|
-
break;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
// Ray from the camera through (x, y) on the image plane, hit on the sphere |P| = D.
|
|
53
|
-
const len = Math.hypot(x, y, 1);
|
|
54
|
-
const ux = x / len;
|
|
55
|
-
const uy = y / len;
|
|
56
|
-
const uz = -1 / len;
|
|
57
|
-
const cu = cd * uz; // C · u with C = (0, 0, cd)
|
|
58
|
-
const t = -cu + Math.sqrt(Math.max(0, cu * cu - cd * cd + D * D));
|
|
59
|
-
const px = ux * t;
|
|
60
|
-
const py = uy * t;
|
|
61
|
-
const pz = cd + uz * t;
|
|
62
|
-
const round = (v) => Math.round(v * 10) / 10;
|
|
63
|
-
return {
|
|
64
|
-
azimuth: round(Math.atan2(px, -pz) / DEG),
|
|
65
|
-
elevation: round(Math.asin(Math.max(-1, Math.min(1, py / D))) / DEG),
|
|
66
|
-
fits,
|
|
67
|
-
};
|
|
22
|
+
export const OVER_THE_SHOULDER = { azimuth: DEFAULT_STAR_PARAMS.azimuth, elevation: DEFAULT_STAR_PARAMS.elevation };
|
|
23
|
+
/**
|
|
24
|
+
* Azimuth / elevation of the default star for a camera on +Z looking at the origin: over the
|
|
25
|
+
* camera's shoulder (`OVER_THE_SHOULDER`), so the world opens lit. The star sits ≥ 0.79 × its
|
|
26
|
+
* distance (≥ 15.8 units) out on +Z, behind any host camera, so the frame never changes it. Hosts
|
|
27
|
+
* use it only when the author has not set azimuth/elevation; `DEFAULT_STAR_PARAMS` stays the
|
|
28
|
+
* host-agnostic fallback.
|
|
29
|
+
*/
|
|
30
|
+
export function defaultStarPlacement(_input) {
|
|
31
|
+
return { azimuth: OVER_THE_SHOULDER.azimuth, elevation: OVER_THE_SHOULDER.elevation, fits: true };
|
|
68
32
|
}
|
package/dist/star/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type { StarParams, StarMultiplicity, SpectralClass } from './params.js';
|
|
|
9
9
|
export { blackbodyColor } from './blackbody.js';
|
|
10
10
|
export type { RGB } from './blackbody.js';
|
|
11
11
|
export { starLayout, starPositions, starSystemPosition, starFocusRadius, flareAt } from './layout.js';
|
|
12
|
-
export { framingDistance, defaultStarPlacement } from './framing.js';
|
|
12
|
+
export { framingDistance, defaultStarPlacement, OVER_THE_SHOULDER } from './framing.js';
|
|
13
13
|
export type { StarPlacement, StarPlacementInput } from './framing.js';
|
|
14
14
|
export type { StarLayout, LaidOutStar, StarOrbit, StarRole, FlareState } from './layout.js';
|
|
15
15
|
export { starParamsFromStellarData, temperatureFromSpectralType, starCountFromPlanetName, luminosityClassFromSpectralType, mainSequenceLuminosity, mainSequenceRadius, mainSequenceTemperature, separationFromAu, youthFromAge, } from './stellarData.js';
|
package/dist/star/index.js
CHANGED
|
@@ -8,7 +8,7 @@ export { STAR_QUALITY, normalizeStarQuality } from './quality.js';
|
|
|
8
8
|
export { DEFAULT_STAR_PARAMS, STAR_PARAM_RANGES, normalizeStarParams, spectralClass, } from './params.js';
|
|
9
9
|
export { blackbodyColor } from './blackbody.js';
|
|
10
10
|
export { starLayout, starPositions, starSystemPosition, starFocusRadius, flareAt } from './layout.js';
|
|
11
|
-
export { framingDistance, defaultStarPlacement } from './framing.js';
|
|
11
|
+
export { framingDistance, defaultStarPlacement, OVER_THE_SHOULDER } from './framing.js';
|
|
12
12
|
export { starParamsFromStellarData, temperatureFromSpectralType, starCountFromPlanetName, luminosityClassFromSpectralType, mainSequenceLuminosity, mainSequenceRadius, mainSequenceTemperature, separationFromAu, youthFromAge, } from './stellarData.js';
|
|
13
13
|
export { DEFAULT_AMBIENT, DEFAULT_STAR_LIGHTING, systemLightColor, keyLightIntensity, fillLightIntensity, lightingFromLegacy, LEGACY_AMBIENT_REFERENCE, LEGACY_AMBIENT_MAX, normalizeStarLighting, parseTint, } from './lighting.js';
|
|
14
14
|
export { minStarDistance, maxStarDistance, SKY_MARGIN_FRACTION, sceneOuterRadius, STAR_DISTANCE_MARGIN, MAX_STAR_ANGULAR_RADIUS_DEG, } from './bounds.js';
|
package/dist/star/layout.js
CHANGED
|
@@ -124,8 +124,7 @@ function distantFor(p, reach) {
|
|
|
124
124
|
if (!p.distantCompanion)
|
|
125
125
|
return null;
|
|
126
126
|
const r = createLcg(`${p.seed}|distant`);
|
|
127
|
-
// Default:
|
|
128
|
-
// behind it, and inside a typical frame when the host itself is placed beside the planet.
|
|
127
|
+
// Default: a little above the host and swung towards the scene's −Z axis — never on top of it.
|
|
129
128
|
const inward = p.azimuth >= 0 ? -1 : 1;
|
|
130
129
|
let azimuth = p.distantAzimuth ?? wrapDeg(p.azimuth + inward * lerp(12, 22, r()));
|
|
131
130
|
let elevation = p.distantElevation ?? Math.min(60, p.elevation + lerp(6, 11, r()));
|
package/dist/star/params.js
CHANGED
|
@@ -10,8 +10,9 @@ export const DEFAULT_STAR_PARAMS = Object.freeze({
|
|
|
10
10
|
separation: 2,
|
|
11
11
|
seed: 1,
|
|
12
12
|
distance: 20,
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
// Over the camera's shoulder (`OVER_THE_SHOULDER` in framing.ts): worlds open on their day side.
|
|
14
|
+
azimuth: 145,
|
|
15
|
+
elevation: 15,
|
|
15
16
|
companionTemperatureK: 0,
|
|
16
17
|
companionRadius: 0,
|
|
17
18
|
distantCompanion: false,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** @param {string | null | undefined} url */
|
|
2
|
+
export function setPublicBase(url: string | null | undefined): void;
|
|
3
|
+
/** @returns {string} */
|
|
4
|
+
export function getPublicBase(): string;
|
|
5
|
+
/**
|
|
6
|
+
* @param {string} path root-relative, relative, or an absolute http(s) URL (returned unchanged).
|
|
7
|
+
* An empty string comes back as is.
|
|
8
|
+
* @returns {string}
|
|
9
|
+
*/
|
|
10
|
+
export function resolvePublicUrl(path: string): string;
|
|
11
|
+
/** @type {string | null} */
|
|
12
|
+
export let __PUBLIC_BASE: string | null;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load texture configuration from remote endpoint or use passed config
|
|
3
|
+
* @param {string} configUrl - Override config URL
|
|
4
|
+
* @param {boolean} useCache - Whether to use cached config if available
|
|
5
|
+
* @returns {Promise<Object>} Texture configuration object
|
|
6
|
+
*/
|
|
7
|
+
export function loadTextureConfig(configUrl?: string, useCache?: boolean): Promise<Object>;
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Object} TextureChoice
|
|
10
|
+
* @property {string} id Catalogue id.
|
|
11
|
+
* @property {string} label Human-readable name.
|
|
12
|
+
* @property {string} url Resolved texture URL (the .ktx2 the world renders).
|
|
13
|
+
* @property {string|null} still Resolved URL of the item's picture — a small thumbnail suitable
|
|
14
|
+
* for showing the texture in a picker. `null` when the catalogue names none.
|
|
15
|
+
*
|
|
16
|
+
* Every catalogue item IS a picture, so a chooser should show it rather than its name. `still` is
|
|
17
|
+
* read straight from the catalogue and never derived from `filename`: the stills do not share one
|
|
18
|
+
* extension, and a wrong guess fails silently (a broken `<img>` just shows nothing).
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Get the full choice records for a category (clouds, moons, etc.) — label, texture URL, and the
|
|
22
|
+
* picture to show for it. The single resolution point for a category's items; `getTextureOptions`
|
|
23
|
+
* is the flat `{ label: url }` projection of this.
|
|
24
|
+
* @param {string} category - Texture category (clouds, moons)
|
|
25
|
+
* @param {Object} config - Optional pre-loaded config object
|
|
26
|
+
* @returns {Promise<TextureChoice[]>} Choice records in catalogue order
|
|
27
|
+
*/
|
|
28
|
+
export function getTextureChoices(category: string, config?: Object): Promise<TextureChoice[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Get texture options for a specific category (clouds, moons, etc.)
|
|
31
|
+
* @param {string} category - Texture category (clouds, moons, skyboxes)
|
|
32
|
+
* @param {Object} config - Optional pre-loaded config object
|
|
33
|
+
* @returns {Promise<Object>} Options object suitable for dropdown option lists
|
|
34
|
+
*/
|
|
35
|
+
export function getTextureOptions(category: string, config?: Object): Promise<Object>;
|
|
36
|
+
/**
|
|
37
|
+
* Get default texture for a category
|
|
38
|
+
* @param {string} category - Texture category
|
|
39
|
+
* @param {Object} config - Optional pre-loaded config object
|
|
40
|
+
* @returns {Promise<string>} Default texture path
|
|
41
|
+
*/
|
|
42
|
+
export function getDefaultTexture(category: string, config?: Object): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Return the configured fallback URL for a given texture if defined.
|
|
45
|
+
* @param {string} category - Texture category (clouds, moons, etc.)
|
|
46
|
+
* @param {string} textureUrl - Resolved texture URL
|
|
47
|
+
* @param {Object|null} config - Optional texture config override
|
|
48
|
+
* @returns {string|null} Resolved fallback texture URL or null
|
|
49
|
+
*/
|
|
50
|
+
export function getTextureFallbackUrl(category: string, textureUrl: string, config?: Object | null): string | null;
|
|
51
|
+
/**
|
|
52
|
+
* Get texture by ID within a category
|
|
53
|
+
* @param {string} category - Texture category
|
|
54
|
+
* @param {string} textureId - Texture ID
|
|
55
|
+
* @param {Object} config - Optional pre-loaded config object
|
|
56
|
+
* @returns {Promise<Object|null>} Texture definition object
|
|
57
|
+
*/
|
|
58
|
+
export function getTextureById(category: string, textureId: string, config?: Object): Promise<Object | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Get full URL for a texture
|
|
61
|
+
* @param {string} category - Texture category
|
|
62
|
+
* @param {string} textureId - Texture ID
|
|
63
|
+
* @param {Object} config - Optional pre-loaded config object
|
|
64
|
+
* @returns {Promise<string|null>} Full texture URL
|
|
65
|
+
*/
|
|
66
|
+
export function getTextureUrl(category: string, textureId: string, config?: Object): Promise<string | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Search textures by tags
|
|
69
|
+
* @param {string} category - Texture category
|
|
70
|
+
* @param {string[]} tags - Tags to search for
|
|
71
|
+
* @param {Object} config - Optional pre-loaded config object
|
|
72
|
+
* @returns {Promise<Object[]>} Array of matching texture definitions
|
|
73
|
+
*/
|
|
74
|
+
export function searchTexturesByTags(category: string, tags: string[], config?: Object): Promise<Object[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Get skybox options formatted for GUI dropdowns
|
|
77
|
+
* @param {Object} config - Optional pre-loaded config object
|
|
78
|
+
* @returns {Promise<Object>} Options object with labels and IDs
|
|
79
|
+
*/
|
|
80
|
+
export function getSkyboxOptions(config?: Object): Promise<Object>;
|
|
81
|
+
/**
|
|
82
|
+
* Get default skybox ID
|
|
83
|
+
* @param {Object} config - Optional pre-loaded config object
|
|
84
|
+
* @returns {Promise<string>} Default skybox ID
|
|
85
|
+
*/
|
|
86
|
+
export function getDefaultSkybox(config?: Object): Promise<string>;
|
|
87
|
+
/**
|
|
88
|
+
* Reload configuration (force refresh)
|
|
89
|
+
* @param {string} configUrl - Override config URL
|
|
90
|
+
* @returns {Promise<Object>} Fresh configuration object
|
|
91
|
+
*/
|
|
92
|
+
export function reloadTextureConfig(configUrl?: string): Promise<Object>;
|
|
93
|
+
/**
|
|
94
|
+
* Get configuration metadata
|
|
95
|
+
* @param {Object} config - Optional pre-loaded config object
|
|
96
|
+
* @returns {Promise<Object>} Configuration metadata
|
|
97
|
+
*/
|
|
98
|
+
export function getConfigMetadata(config?: Object): Promise<Object>;
|
|
99
|
+
export type TextureChoice = {
|
|
100
|
+
/**
|
|
101
|
+
* Catalogue id.
|
|
102
|
+
*/
|
|
103
|
+
id: string;
|
|
104
|
+
/**
|
|
105
|
+
* Human-readable name.
|
|
106
|
+
*/
|
|
107
|
+
label: string;
|
|
108
|
+
/**
|
|
109
|
+
* Resolved texture URL (the .ktx2 the world renders).
|
|
110
|
+
*/
|
|
111
|
+
url: string;
|
|
112
|
+
/**
|
|
113
|
+
* Resolved URL of the item's picture — a small thumbnail suitable
|
|
114
|
+
* for showing the texture in a picker. `null` when the catalogue names none.
|
|
115
|
+
*
|
|
116
|
+
* Every catalogue item IS a picture, so a chooser should show it rather than its name. `still` is
|
|
117
|
+
* read straight from the catalogue and never derived from `filename`: the stills do not share one
|
|
118
|
+
* extension, and a wrong guess fails silently (a broken `<img>` just shows nothing).
|
|
119
|
+
*/
|
|
120
|
+
still: string | null;
|
|
121
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensure a scene has the default hemisphere + ambient lights. Idempotent PER SCENE.
|
|
3
|
+
*
|
|
4
|
+
* A multi-orbiter realm renders N independent scenes through one renderer. A module-level
|
|
5
|
+
* singleton light is wrong twice over — it's only added to the FIRST scene, and a THREE light can
|
|
6
|
+
* live in just one scene (adding it to a second removes it from the first), so scenes 2..N rendered
|
|
7
|
+
* DARK ("only one entangled world"). So create + add the lights PER scene, keyed by name so a
|
|
8
|
+
* re-call on the same scene is a no-op. Single-orbiter (one scene) is unchanged.
|
|
9
|
+
*
|
|
10
|
+
* @param {import('three').Scene} scene
|
|
11
|
+
* @returns {{ hemi: import('three').HemisphereLight, ambient: import('three').AmbientLight }}
|
|
12
|
+
*/
|
|
13
|
+
export function ensureDefaultLights(scene: import("three").Scene): {
|
|
14
|
+
hemi: import("three").HemisphereLight;
|
|
15
|
+
ambient: import("three").AmbientLight;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Apply a lighting patch to ONE scene's default lights.
|
|
19
|
+
*
|
|
20
|
+
* The scene is required. This used to address module-global light refs pointing at whichever scene
|
|
21
|
+
* was ensured last, so on a page rendering several scenes every lighting update landed on one of
|
|
22
|
+
* them — a shared-renderer page (N feed worlds, N orbiters) lit the wrong world.
|
|
23
|
+
*
|
|
24
|
+
* Every field is optional; an omitted one leaves that part of the lighting as it is.
|
|
25
|
+
*
|
|
26
|
+
* @param {import('three').Scene} scene
|
|
27
|
+
* @param {object} [patch]
|
|
28
|
+
* @param {number} [patch.ambientIntensity] ambient light intensity (clamped at 0)
|
|
29
|
+
* @param {number} [patch.diffuseIntensity] hemisphere light intensity (clamped at 0)
|
|
30
|
+
* @param {import('three').Color | number | string} [patch.lightColor] hemisphere light colour
|
|
31
|
+
* @param {{ x: number, y?: number, z?: number }} [patch.lightDirection] hemisphere light direction
|
|
32
|
+
* @param {boolean} [patch.hemisphere] switch the hemisphere light on or off
|
|
33
|
+
*/
|
|
34
|
+
export function updateDefaultLights(scene: import("three").Scene, { ambientIntensity, diffuseIntensity, lightColor, lightDirection, hemisphere }?: {
|
|
35
|
+
ambientIntensity?: number | undefined;
|
|
36
|
+
diffuseIntensity?: number | undefined;
|
|
37
|
+
lightColor?: string | number | THREE.Color | undefined;
|
|
38
|
+
lightDirection?: {
|
|
39
|
+
x: number;
|
|
40
|
+
y?: number;
|
|
41
|
+
z?: number;
|
|
42
|
+
} | undefined;
|
|
43
|
+
hemisphere?: boolean | undefined;
|
|
44
|
+
}): void;
|
|
45
|
+
/**
|
|
46
|
+
* Switch a scene's default hemisphere light on or off (the ambient light is untouched). Hosts turn it
|
|
47
|
+
* off when a directional light — the star — lights the scene, so night sides can read.
|
|
48
|
+
*
|
|
49
|
+
* @param {import('three').Scene} scene
|
|
50
|
+
* @param {boolean} on
|
|
51
|
+
*/
|
|
52
|
+
export function setHemisphereEnabled(scene: import("three").Scene, on: boolean): void;
|
|
53
|
+
/** @param {import('three').Scene} scene */
|
|
54
|
+
export function addDefaultLights(scene: import("three").Scene): {
|
|
55
|
+
hemi: import("three").HemisphereLight;
|
|
56
|
+
ambient: import("three").AmbientLight;
|
|
57
|
+
};
|
|
58
|
+
import * as THREE from 'three';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string} url `.ktx2` goes through the renderer's KTX2 transcoder; anything else through
|
|
3
|
+
* THREE.TextureLoader.
|
|
4
|
+
* @param {object} [opts]
|
|
5
|
+
* @param {AbortSignal} [opts.signal] an abort during the load rejects the promise.
|
|
6
|
+
* @param {import('three').WebGLRenderer | null} [opts.renderer] REQUIRED for a `.ktx2` url.
|
|
7
|
+
*/
|
|
8
|
+
export function loadTexture(url: string, { signal, renderer }?: {
|
|
9
|
+
signal?: AbortSignal | undefined;
|
|
10
|
+
renderer?: THREE.WebGLRenderer | null | undefined;
|
|
11
|
+
}): Promise<any>;
|
|
12
|
+
import * as THREE from 'three';
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export function normalizeSkycubeName(raw: any): string;
|
|
2
|
+
export function buildSkycubefaceKeys(skycubeId: any, extension?: string): {
|
|
3
|
+
right: string;
|
|
4
|
+
left: string;
|
|
5
|
+
top: string;
|
|
6
|
+
bottom: string;
|
|
7
|
+
front: string;
|
|
8
|
+
back: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Main loader function - always uses explicit face URLs.
|
|
12
|
+
* `renderer` binds the KTX2 transcoder to the right WebGL context. REQUIRED (3.0) when the KTX2
|
|
13
|
+
* path is taken — the old `window.__EW_RENDERER` fallback is gone; thread the owning view's
|
|
14
|
+
* renderer. (The PNG/JPG path is renderer-agnostic, so its absence only bites on KTX2.)
|
|
15
|
+
*
|
|
16
|
+
* @param {object} [opts]
|
|
17
|
+
* @param {{ right: string, left: string, top: string, bottom: string, front: string, back: string }} [opts.faceKeys]
|
|
18
|
+
* explicit face URLs; when absent they are built from `skycubeName`.
|
|
19
|
+
* @param {string} [opts.skycubeName] skybox id (e.g. `'001'`), used when `faceKeys` is absent.
|
|
20
|
+
* @param {boolean} [opts.preferKTX2=true]
|
|
21
|
+
* @param {boolean} [opts.forceLow] force (or forbid) the low-resolution faces; omitted = detect the device.
|
|
22
|
+
* @param {import('three').WebGLRenderer | null} [opts.renderer]
|
|
23
|
+
* @returns {Promise<SkyboxResource>} pass it to `setBackground`.
|
|
24
|
+
*/
|
|
25
|
+
export function loadCubeMap({ faceKeys, skycubeName, preferKTX2, forceLow, renderer }?: {
|
|
26
|
+
faceKeys?: {
|
|
27
|
+
right: string;
|
|
28
|
+
left: string;
|
|
29
|
+
top: string;
|
|
30
|
+
bottom: string;
|
|
31
|
+
front: string;
|
|
32
|
+
back: string;
|
|
33
|
+
} | undefined;
|
|
34
|
+
skycubeName?: string | undefined;
|
|
35
|
+
preferKTX2?: boolean | undefined;
|
|
36
|
+
forceLow?: boolean | undefined;
|
|
37
|
+
renderer?: THREE.WebGLRenderer | null | undefined;
|
|
38
|
+
}): Promise<SkyboxResource>;
|
|
39
|
+
/**
|
|
40
|
+
* What `loadCubeMap` resolves to: a skybox mesh wrapper (the KTX2 path) or a cube texture (the
|
|
41
|
+
* PNG/JPG path). Read `mesh` to tell them apart.
|
|
42
|
+
* @typedef {{ __ewType: 'skybox-mesh', mesh: import('three').Mesh } | (import('three').CubeTexture & { mesh?: undefined })} SkyboxResource
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* Show a loaded skybox as the scene's background. A previous skybox mesh or cube-texture background is
|
|
46
|
+
* disposed (a plain-texture background is not). Takes what `loadCubeMap` resolved to (or any texture);
|
|
47
|
+
* anything else, `null` included, clears it.
|
|
48
|
+
*
|
|
49
|
+
* @param {import('three').Scene} scene
|
|
50
|
+
* @param {unknown} resource
|
|
51
|
+
*/
|
|
52
|
+
export function setBackground(scene: import("three").Scene, resource: unknown): void;
|
|
53
|
+
/**
|
|
54
|
+
* @param {import('three').Scene} scene
|
|
55
|
+
* @param {{ renderer?: import('three').WebGLRenderer | null }} [opts]
|
|
56
|
+
*/
|
|
57
|
+
export function initSpaceScene(scene: import("three").Scene, { renderer }?: {
|
|
58
|
+
renderer?: import("three").WebGLRenderer | null;
|
|
59
|
+
}): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* What `loadCubeMap` resolves to: a skybox mesh wrapper (the KTX2 path) or a cube texture (the
|
|
62
|
+
* PNG/JPG path). Read `mesh` to tell them apart.
|
|
63
|
+
*/
|
|
64
|
+
export type SkyboxResource = {
|
|
65
|
+
__ewType: "skybox-mesh";
|
|
66
|
+
mesh: import("three").Mesh;
|
|
67
|
+
} | (import("three").CubeTexture & {
|
|
68
|
+
mesh?: undefined;
|
|
69
|
+
});
|
|
70
|
+
import * as THREE from 'three';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string} url
|
|
3
|
+
* @param {object} [opts] `renderer` is REQUIRED at runtime (throws without one).
|
|
4
|
+
* @param {number} [opts.retries=3] load attempts before giving up.
|
|
5
|
+
* @param {AbortSignal} [opts.signal] rejects the load on abort.
|
|
6
|
+
* @param {(event: ProgressEvent) => void} [opts.onProgress]
|
|
7
|
+
* @param {object} [opts.applyFlags] material flags (`forceOpaque`, `wireframe`) applied to every mesh.
|
|
8
|
+
* @param {boolean} [opts.withCredentials=false]
|
|
9
|
+
* @param {number} [opts.emissiveIntensity=1] self-glow of textured materials (their map doubles as the
|
|
10
|
+
* emissive map). 1 keeps the old flat-lit look; with a directional star light pass ≈0.1–0.15 so the
|
|
11
|
+
* night side reads.
|
|
12
|
+
* @param {import('three').WebGLRenderer} opts.renderer REQUIRED (3.0): the renderer this GLB's
|
|
13
|
+
* textures bind to. A page with several renderers has no single correct global, so the old
|
|
14
|
+
* `window.__EW_RENDERER` fallback is gone — thread the owning view's renderer.
|
|
15
|
+
*/
|
|
16
|
+
export function loadGLB(url: string, { retries, signal, onProgress, applyFlags, withCredentials, renderer, emissiveIntensity }?: {
|
|
17
|
+
retries?: number | undefined;
|
|
18
|
+
signal?: AbortSignal | undefined;
|
|
19
|
+
onProgress?: ((event: ProgressEvent) => void) | undefined;
|
|
20
|
+
applyFlags?: object | undefined;
|
|
21
|
+
withCredentials?: boolean | undefined;
|
|
22
|
+
emissiveIntensity?: number | undefined;
|
|
23
|
+
renderer: import("three").WebGLRenderer;
|
|
24
|
+
}): Promise<any>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { loadGLB } from "./glbLoader.js";
|
|
2
|
+
export { loadTexture } from "./bodyTextureLoader.js";
|
|
3
|
+
export type SkyboxResource = import("./cubeMapLoader.js").SkyboxResource;
|
|
4
|
+
export { loadCubeMap, setBackground, normalizeSkycubeName, buildSkycubefaceKeys } from "./cubeMapLoader.js";
|
|
5
|
+
export { getKTX2LoaderForRenderer, disposeKTX2LoaderForRenderer } from "./ktx2.js";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The KTX2Loader bound to `renderer` — REQUIRED (3.0). The old `window.__EW_RENDERER` fallback let
|
|
3
|
+
* call sites compile while silently binding the transcoder to whichever renderer a page published
|
|
4
|
+
* last; on any multi-view page that meant untextured worlds. Every caller now threads its own
|
|
5
|
+
* renderer, so a missing one is a caller bug and fails loudly here rather than as a dark planet.
|
|
6
|
+
* @param {import('three').WebGLRenderer} renderer
|
|
7
|
+
* @returns {KTX2Loader}
|
|
8
|
+
*/
|
|
9
|
+
export function getKTX2LoaderForRenderer(renderer: import("three").WebGLRenderer): KTX2Loader;
|
|
10
|
+
/**
|
|
11
|
+
* Dispose and forget the KTX2Loader for a renderer — call on that renderer's / scene's teardown so the
|
|
12
|
+
* transcoder workers are terminated (avoids leaking worker threads + GPU memory across view churn).
|
|
13
|
+
* @param {import('three').WebGLRenderer} renderer
|
|
14
|
+
*/
|
|
15
|
+
export function disposeKTX2LoaderForRenderer(renderer: import("three").WebGLRenderer): void;
|
|
16
|
+
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {object} [opts]
|
|
3
|
+
* @param {number} [opts.count=0] 0 or less resolves to null.
|
|
4
|
+
* @param {number} [opts.orbitRadius=1.5]
|
|
5
|
+
* @param {string} [opts.textureKTX2]
|
|
6
|
+
* @param {string} [opts.texturePNG]
|
|
7
|
+
* @param {string | null} [opts.textureFallback] used instead of `texturePNG` when set.
|
|
8
|
+
* @param {boolean} [opts.useTexture=true]
|
|
9
|
+
* @param {number | string | null} [opts.seed] deterministic positions when set.
|
|
10
|
+
* @param {string | null} [opts.textureKey] replaces `textureKTX2` when set (the fallback stays
|
|
11
|
+
* `textureFallback` or `texturePNG`).
|
|
12
|
+
* @param {string} [opts.moonColor='#ffffff']
|
|
13
|
+
* @param {number} [opts.brightness=1.15]
|
|
14
|
+
* @param {number} [opts.emissiveColor=0x333333]
|
|
15
|
+
* @param {number} [opts.emissiveIntensity=0.18]
|
|
16
|
+
* @param {number} [opts.emissiveLift] night-side self-glow 0..1; omitted = `emissiveIntensity`.
|
|
17
|
+
* @param {number} [opts.roughness=0.85]
|
|
18
|
+
* @param {number} [opts.metalness=0]
|
|
19
|
+
* @param {boolean} [opts.debug=true]
|
|
20
|
+
* @param {boolean} [opts.smooth=true]
|
|
21
|
+
* @param {number} [opts.geometryWidthSegments=16]
|
|
22
|
+
* @param {number} [opts.geometryHeightSegments=12]
|
|
23
|
+
* @param {boolean} [opts.useBumpFromColor=true]
|
|
24
|
+
* @param {number} [opts.bumpScale=0.15]
|
|
25
|
+
* @param {boolean} [opts.debugShowUvGrid=false]
|
|
26
|
+
* @param {boolean} [opts.debugShowReferenceMoon=false]
|
|
27
|
+
* @param {number} [opts.referenceMoonScale=0.25]
|
|
28
|
+
* @param {boolean} [opts.useEmissiveMapFromTexture=true]
|
|
29
|
+
* @param {import('three').WebGLRenderer | null} [opts.renderer] binds the KTX2 moon texture.
|
|
30
|
+
*/
|
|
31
|
+
export function generateMoons({ count, orbitRadius, textureKTX2, texturePNG, textureFallback, useTexture, seed, textureKey, moonColor, brightness, emissiveColor, emissiveIntensity, emissiveLift, roughness, metalness, debug, smooth, geometryWidthSegments, geometryHeightSegments, useBumpFromColor, bumpScale, debugShowUvGrid, debugShowReferenceMoon, referenceMoonScale, useEmissiveMapFromTexture, renderer, }?: {
|
|
32
|
+
count?: number | undefined;
|
|
33
|
+
orbitRadius?: number | undefined;
|
|
34
|
+
textureKTX2?: string | undefined;
|
|
35
|
+
texturePNG?: string | undefined;
|
|
36
|
+
textureFallback?: string | null | undefined;
|
|
37
|
+
useTexture?: boolean | undefined;
|
|
38
|
+
seed?: string | number | null | undefined;
|
|
39
|
+
textureKey?: string | null | undefined;
|
|
40
|
+
moonColor?: string | undefined;
|
|
41
|
+
brightness?: number | undefined;
|
|
42
|
+
emissiveColor?: number | undefined;
|
|
43
|
+
emissiveIntensity?: number | undefined;
|
|
44
|
+
emissiveLift?: number | undefined;
|
|
45
|
+
roughness?: number | undefined;
|
|
46
|
+
metalness?: number | undefined;
|
|
47
|
+
debug?: boolean | undefined;
|
|
48
|
+
smooth?: boolean | undefined;
|
|
49
|
+
geometryWidthSegments?: number | undefined;
|
|
50
|
+
geometryHeightSegments?: number | undefined;
|
|
51
|
+
useBumpFromColor?: boolean | undefined;
|
|
52
|
+
bumpScale?: number | undefined;
|
|
53
|
+
debugShowUvGrid?: boolean | undefined;
|
|
54
|
+
debugShowReferenceMoon?: boolean | undefined;
|
|
55
|
+
referenceMoonScale?: number | undefined;
|
|
56
|
+
useEmissiveMapFromTexture?: boolean | undefined;
|
|
57
|
+
renderer?: THREE.WebGLRenderer | null | undefined;
|
|
58
|
+
}): Promise<THREE.Group<THREE.Object3DEventMap> | null>;
|
|
59
|
+
export const DEFAULT_MOON_TEX_KTX2: string;
|
|
60
|
+
export const DEFAULT_MOON_TEX_PNG: string;
|
|
61
|
+
/** Radius of the shared moon sphere before per-moon scale. */
|
|
62
|
+
export const MOON_BASE_RADIUS: 0.1;
|
|
63
|
+
/** Per-moon scale range: MIN + random * SPAN. */
|
|
64
|
+
export const MOON_SCALE_MIN: 0.07;
|
|
65
|
+
export const MOON_SCALE_SPAN: 0.15;
|
|
66
|
+
/** Largest moon radius in scene units (base radius × largest scale). */
|
|
67
|
+
export const MOON_MAX_RADIUS: number;
|
|
68
|
+
/** Each moon's orbit radius varies by ± half of this around the requested orbit. */
|
|
69
|
+
export const MOON_ORBIT_SCATTER: 0.22;
|
|
70
|
+
/** Each moon sits up to ± half of this above or below the orbit plane. */
|
|
71
|
+
export const MOON_HEIGHT_SCATTER: 0.12;
|
|
72
|
+
import * as THREE from 'three';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class MoonsManager {
|
|
2
|
+
/**
|
|
3
|
+
* @param {import('three').Scene} scene
|
|
4
|
+
* @param {object} [opts]
|
|
5
|
+
* @param {import('three').WebGLRenderer | null} [opts.renderer] renderer the moon texture binds to (KTX2).
|
|
6
|
+
*/
|
|
7
|
+
constructor(scene: import("three").Scene, { renderer }?: {
|
|
8
|
+
renderer?: THREE.WebGLRenderer | null | undefined;
|
|
9
|
+
});
|
|
10
|
+
scene: THREE.Scene;
|
|
11
|
+
renderer: THREE.WebGLRenderer | null | undefined;
|
|
12
|
+
group: THREE.Group<THREE.Object3DEventMap> | null;
|
|
13
|
+
_opId: number;
|
|
14
|
+
_emissiveLift: number | undefined;
|
|
15
|
+
setAmount(count: any, opts?: {}): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Night-side self-glow 0..1, applied in place to the live moons and kept for later rebuilds.
|
|
18
|
+
* Low values (≈0.05) let a star-lit scene show the moons' dark sides.
|
|
19
|
+
*/
|
|
20
|
+
setEmissiveLift(v: any): void;
|
|
21
|
+
/**
|
|
22
|
+
* Remove the moons from the scene and free their GPU resources. `scene.remove(group)` alone leaks
|
|
23
|
+
* the instanced geometry, materials and the shared moon texture on every view teardown.
|
|
24
|
+
*/
|
|
25
|
+
dispose(): void;
|
|
26
|
+
}
|
|
27
|
+
import * as THREE from 'three';
|