@scenography/plugin-light 0.2.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/dist/data-CcMZWQIz.cjs +41 -0
- package/dist/data-CcMZWQIz.cjs.map +1 -0
- package/dist/data-bkULec9x.mjs +30 -0
- package/dist/data-bkULec9x.mjs.map +1 -0
- package/dist/data.cjs +4 -0
- package/dist/data.d.cts +2 -0
- package/dist/data.d.mts +2 -0
- package/dist/data.mjs +2 -0
- package/dist/index-CfFuhLoP.d.cts +86 -0
- package/dist/index-CfFuhLoP.d.mts +86 -0
- package/dist/index.cjs +177 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +49 -0
- package/dist/index.d.mts +49 -0
- package/dist/index.mjs +172 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
let _scenography_scene = require("@scenography/scene");
|
|
2
|
+
//#region src/data/validate.ts
|
|
3
|
+
const POSITIONED = new Set([
|
|
4
|
+
"directional",
|
|
5
|
+
"point",
|
|
6
|
+
"spot"
|
|
7
|
+
]);
|
|
8
|
+
const LIGHT_TYPES = new Set([
|
|
9
|
+
...POSITIONED,
|
|
10
|
+
"ambient",
|
|
11
|
+
"hemisphere"
|
|
12
|
+
]);
|
|
13
|
+
const validateLight = (light) => (0, _scenography_scene.validate)([
|
|
14
|
+
(0, _scenography_scene.existsProp)("id", "Light is missing an id."),
|
|
15
|
+
(0, _scenography_scene.propIs)("intensity", _scenography_scene.isFiniteNumber, "intensity must be a finite number."),
|
|
16
|
+
(0, _scenography_scene.when)((l) => POSITIONED.has(l.type), (0, _scenography_scene.existsProp)("position"), (0, _scenography_scene.propIs)("position", _scenography_scene.isVec3, "position must be [x, y, z]."), (0, _scenography_scene.propIs)("target", _scenography_scene.isVec3, "target must be [x, y, z].")),
|
|
17
|
+
(0, _scenography_scene.when)((l) => !(0, _scenography_scene.isOneOf)(LIGHT_TYPES)(l.type), (0, _scenography_scene.fail)("type", "unknown light type."))
|
|
18
|
+
])(light);
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/data/plugin.ts
|
|
21
|
+
/** The data half of the light plugin: owns the `lights` scene key (a collection). */
|
|
22
|
+
const lightData = {
|
|
23
|
+
kind: "lights",
|
|
24
|
+
cardinality: "many",
|
|
25
|
+
validate: (light) => validateLight(light)
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
Object.defineProperty(exports, "lightData", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function() {
|
|
31
|
+
return lightData;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(exports, "validateLight", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function() {
|
|
37
|
+
return validateLight;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=data-CcMZWQIz.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-CcMZWQIz.cjs","names":["isFiniteNumber","isVec3"],"sources":["../src/data/validate.ts","../src/data/plugin.ts"],"sourcesContent":["import {\n existsProp,\n fail,\n isFiniteNumber,\n isOneOf,\n isVec3,\n propIs,\n validate,\n when,\n type ValidationResult,\n} from \"@scenography/scene\";\n\nimport type { Light } from \"./light\";\n\nconst POSITIONED: ReadonlySet<string> = new Set([\"directional\", \"point\", \"spot\"]);\nconst LIGHT_TYPES: ReadonlySet<string> = new Set([...POSITIONED, \"ambient\", \"hemisphere\"]);\n\nexport const validateLight = (light: Light): ValidationResult =>\n validate<Light>([\n existsProp(\"id\", \"Light is missing an id.\"),\n propIs(\"intensity\", isFiniteNumber, \"intensity must be a finite number.\"),\n when(\n (l: Light) => POSITIONED.has(l.type),\n existsProp(\"position\"),\n propIs(\"position\", isVec3, \"position must be [x, y, z].\"),\n propIs(\"target\", isVec3, \"target must be [x, y, z].\"),\n ),\n when(\n (l: Light) => !isOneOf(LIGHT_TYPES)(l.type),\n fail(\"type\", \"unknown light type.\"),\n ),\n ])(light);\n","import type { DataPlugin } from \"@scenography/scene\";\n\nimport { validateLight } from \"./validate\";\nimport type { Light } from \"./light\";\n\n/** The data half of the light plugin: owns the `lights` scene key (a collection). */\nexport const lightData: DataPlugin<Light> = {\n kind: \"lights\",\n cardinality: \"many\",\n validate: (light) => validateLight(light),\n};\n"],"mappings":";;AAcA,MAAM,aAAkC,IAAI,IAAI;CAAC;CAAe;CAAS;AAAM,CAAC;AAChF,MAAM,cAAmC,IAAI,IAAI;CAAC,GAAG;CAAY;CAAW;AAAY,CAAC;AAEzF,MAAa,iBAAiB,WAAA,GAAA,mBAAA,SAAA,CACZ;oCACH,MAAM,yBAAyB;gCACnC,aAAaA,mBAAAA,gBAAgB,oCAAoC;+BAErE,MAAa,WAAW,IAAI,EAAE,IAAI,IAAA,GAAA,mBAAA,WAAA,CACxB,UAAU,IAAA,GAAA,mBAAA,OAAA,CACd,YAAYC,mBAAAA,QAAQ,6BAA6B,IAAA,GAAA,mBAAA,OAAA,CACjD,UAAUA,mBAAAA,QAAQ,2BAA2B,CACtD;+BAEG,MAAa,EAAA,GAAA,mBAAA,QAAA,CAAS,WAAW,CAAC,CAAC,EAAE,IAAI,IAAA,GAAA,mBAAA,KAAA,CACrC,QAAQ,qBAAqB,CACpC;AACF,CAAC,CAAC,CAAC,KAAK;;;;ACzBV,MAAa,YAA+B;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,UAAU,cAAc,KAAK;AAC1C"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsProp, fail, isFiniteNumber, isOneOf, isVec3, propIs, validate, when } from "@scenography/scene";
|
|
2
|
+
//#region src/data/validate.ts
|
|
3
|
+
const POSITIONED = new Set([
|
|
4
|
+
"directional",
|
|
5
|
+
"point",
|
|
6
|
+
"spot"
|
|
7
|
+
]);
|
|
8
|
+
const LIGHT_TYPES = new Set([
|
|
9
|
+
...POSITIONED,
|
|
10
|
+
"ambient",
|
|
11
|
+
"hemisphere"
|
|
12
|
+
]);
|
|
13
|
+
const validateLight = (light) => validate([
|
|
14
|
+
existsProp("id", "Light is missing an id."),
|
|
15
|
+
propIs("intensity", isFiniteNumber, "intensity must be a finite number."),
|
|
16
|
+
when((l) => POSITIONED.has(l.type), existsProp("position"), propIs("position", isVec3, "position must be [x, y, z]."), propIs("target", isVec3, "target must be [x, y, z].")),
|
|
17
|
+
when((l) => !isOneOf(LIGHT_TYPES)(l.type), fail("type", "unknown light type."))
|
|
18
|
+
])(light);
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/data/plugin.ts
|
|
21
|
+
/** The data half of the light plugin: owns the `lights` scene key (a collection). */
|
|
22
|
+
const lightData = {
|
|
23
|
+
kind: "lights",
|
|
24
|
+
cardinality: "many",
|
|
25
|
+
validate: (light) => validateLight(light)
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { validateLight as n, lightData as t };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=data-bkULec9x.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-bkULec9x.mjs","names":[],"sources":["../src/data/validate.ts","../src/data/plugin.ts"],"sourcesContent":["import {\n existsProp,\n fail,\n isFiniteNumber,\n isOneOf,\n isVec3,\n propIs,\n validate,\n when,\n type ValidationResult,\n} from \"@scenography/scene\";\n\nimport type { Light } from \"./light\";\n\nconst POSITIONED: ReadonlySet<string> = new Set([\"directional\", \"point\", \"spot\"]);\nconst LIGHT_TYPES: ReadonlySet<string> = new Set([...POSITIONED, \"ambient\", \"hemisphere\"]);\n\nexport const validateLight = (light: Light): ValidationResult =>\n validate<Light>([\n existsProp(\"id\", \"Light is missing an id.\"),\n propIs(\"intensity\", isFiniteNumber, \"intensity must be a finite number.\"),\n when(\n (l: Light) => POSITIONED.has(l.type),\n existsProp(\"position\"),\n propIs(\"position\", isVec3, \"position must be [x, y, z].\"),\n propIs(\"target\", isVec3, \"target must be [x, y, z].\"),\n ),\n when(\n (l: Light) => !isOneOf(LIGHT_TYPES)(l.type),\n fail(\"type\", \"unknown light type.\"),\n ),\n ])(light);\n","import type { DataPlugin } from \"@scenography/scene\";\n\nimport { validateLight } from \"./validate\";\nimport type { Light } from \"./light\";\n\n/** The data half of the light plugin: owns the `lights` scene key (a collection). */\nexport const lightData: DataPlugin<Light> = {\n kind: \"lights\",\n cardinality: \"many\",\n validate: (light) => validateLight(light),\n};\n"],"mappings":";;AAcA,MAAM,aAAkC,IAAI,IAAI;CAAC;CAAe;CAAS;AAAM,CAAC;AAChF,MAAM,cAAmC,IAAI,IAAI;CAAC,GAAG;CAAY;CAAW;AAAY,CAAC;AAEzF,MAAa,iBAAiB,UAC5B,SAAgB;CACd,WAAW,MAAM,yBAAyB;CAC1C,OAAO,aAAa,gBAAgB,oCAAoC;CACxE,MACG,MAAa,WAAW,IAAI,EAAE,IAAI,GACnC,WAAW,UAAU,GACrB,OAAO,YAAY,QAAQ,6BAA6B,GACxD,OAAO,UAAU,QAAQ,2BAA2B,CACtD;CACA,MACG,MAAa,CAAC,QAAQ,WAAW,CAAC,CAAC,EAAE,IAAI,GAC1C,KAAK,QAAQ,qBAAqB,CACpC;AACF,CAAC,CAAC,CAAC,KAAK;;;;ACzBV,MAAa,YAA+B;CAC1C,MAAM;CACN,aAAa;CACb,WAAW,UAAU,cAAc,KAAK;AAC1C"}
|
package/dist/data.cjs
ADDED
package/dist/data.d.cts
ADDED
package/dist/data.d.mts
ADDED
package/dist/data.mjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DataPlugin, ValidationResult, Vec3 } from "@scenography/scene";
|
|
2
|
+
|
|
3
|
+
//#region src/data/light.d.ts
|
|
4
|
+
/** Fields shared by every light variant. */
|
|
5
|
+
interface LightBase {
|
|
6
|
+
id: string;
|
|
7
|
+
/** CSS-style color. Defaults to white. */
|
|
8
|
+
color?: string;
|
|
9
|
+
/** Brightness multiplier. Sensible defaults vary by `type`. */
|
|
10
|
+
intensity?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Shadow-casting settings for a light. Only `directional`, `spot` and `point`
|
|
14
|
+
* lights can cast. `true` enables shadows with engine defaults; the object form
|
|
15
|
+
* tunes quality and the shadow camera. Runtime detail — but declared as data so
|
|
16
|
+
* the look is part of the serializable scene.
|
|
17
|
+
*/
|
|
18
|
+
interface LightShadow {
|
|
19
|
+
/** Shadow map resolution in px (square). Defaults to 1024. */
|
|
20
|
+
mapSize?: number;
|
|
21
|
+
/** Depth bias to fight shadow acne. Defaults to 0. */
|
|
22
|
+
bias?: number;
|
|
23
|
+
/** Normal-offset bias, softer fix for acne/peter-panning. Defaults to 0. */
|
|
24
|
+
normalBias?: number;
|
|
25
|
+
/** Near plane of the shadow camera. */
|
|
26
|
+
near?: number;
|
|
27
|
+
/** Far plane of the shadow camera. */
|
|
28
|
+
far?: number;
|
|
29
|
+
/**
|
|
30
|
+
* `directional` only: half-size of the orthographic frustum in world units —
|
|
31
|
+
* make it large enough to cover the area that should receive shadows.
|
|
32
|
+
*/
|
|
33
|
+
size?: number;
|
|
34
|
+
}
|
|
35
|
+
/** Shorthand: `true` for defaults, or a settings object. */
|
|
36
|
+
type ShadowConfig = boolean | LightShadow;
|
|
37
|
+
/**
|
|
38
|
+
* A light in the scene. Extensible via `type`; covers uniform fill (`ambient`,
|
|
39
|
+
* `hemisphere`), a sun-like source (`directional`), an omni source (`point`) and
|
|
40
|
+
* a cone spotlight (`spot`). Behavior (dimming, animation) is wired by `id` in
|
|
41
|
+
* the runtime through `ctx.lights` — the definition stays pure data.
|
|
42
|
+
*/
|
|
43
|
+
type Light = (LightBase & {
|
|
44
|
+
type: "ambient";
|
|
45
|
+
}) | (LightBase & {
|
|
46
|
+
type: "hemisphere"; /** Color bounced from below. Defaults to a dark gray. */
|
|
47
|
+
groundColor?: string;
|
|
48
|
+
}) | (LightBase & {
|
|
49
|
+
type: "directional"; /** World position the parallel rays emanate from. */
|
|
50
|
+
position: Vec3; /** Point the light aims at. Defaults to the origin. */
|
|
51
|
+
target?: Vec3; /** Cast shadows from this light. */
|
|
52
|
+
shadow?: ShadowConfig;
|
|
53
|
+
}) | (LightBase & {
|
|
54
|
+
type: "point"; /** World position of the source. */
|
|
55
|
+
position: Vec3; /** Range in world units; `0` (default) is infinite. */
|
|
56
|
+
distance?: number; /** Falloff exponent. Defaults to `2` (physically correct). */
|
|
57
|
+
decay?: number; /** Cast shadows from this light. */
|
|
58
|
+
shadow?: ShadowConfig;
|
|
59
|
+
}) | (LightBase & {
|
|
60
|
+
type: "spot"; /** World position of the source. */
|
|
61
|
+
position: Vec3; /** Point the cone aims at. Defaults to the origin. */
|
|
62
|
+
target?: Vec3; /** Cone half-angle in radians. */
|
|
63
|
+
angle?: number; /** Soft edge, `0`..`1`. Defaults to `0`. */
|
|
64
|
+
penumbra?: number; /** Range in world units; `0` (default) is infinite. */
|
|
65
|
+
distance?: number; /** Falloff exponent. Defaults to `2`. */
|
|
66
|
+
decay?: number; /** Cast shadows from this light. */
|
|
67
|
+
shadow?: ShadowConfig;
|
|
68
|
+
});
|
|
69
|
+
/** The discriminant values a `Light` can take. */
|
|
70
|
+
type LightType = Light["type"];
|
|
71
|
+
declare module "@scenography/scene" {
|
|
72
|
+
interface Scene {
|
|
73
|
+
/** Lights in the space — provided by `@scenography/plugin-light`. */
|
|
74
|
+
lights?: Light[];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/data/validate.d.ts
|
|
79
|
+
declare const validateLight: (light: Light) => ValidationResult;
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/data/plugin.d.ts
|
|
82
|
+
/** The data half of the light plugin: owns the `lights` scene key (a collection). */
|
|
83
|
+
declare const lightData: DataPlugin<Light>;
|
|
84
|
+
//#endregion
|
|
85
|
+
export { LightType as a, LightShadow as i, validateLight as n, Light as r, lightData as t };
|
|
86
|
+
//# sourceMappingURL=index-CfFuhLoP.d.cts.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DataPlugin, ValidationResult, Vec3 } from "@scenography/scene";
|
|
2
|
+
|
|
3
|
+
//#region src/data/light.d.ts
|
|
4
|
+
/** Fields shared by every light variant. */
|
|
5
|
+
interface LightBase {
|
|
6
|
+
id: string;
|
|
7
|
+
/** CSS-style color. Defaults to white. */
|
|
8
|
+
color?: string;
|
|
9
|
+
/** Brightness multiplier. Sensible defaults vary by `type`. */
|
|
10
|
+
intensity?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Shadow-casting settings for a light. Only `directional`, `spot` and `point`
|
|
14
|
+
* lights can cast. `true` enables shadows with engine defaults; the object form
|
|
15
|
+
* tunes quality and the shadow camera. Runtime detail — but declared as data so
|
|
16
|
+
* the look is part of the serializable scene.
|
|
17
|
+
*/
|
|
18
|
+
interface LightShadow {
|
|
19
|
+
/** Shadow map resolution in px (square). Defaults to 1024. */
|
|
20
|
+
mapSize?: number;
|
|
21
|
+
/** Depth bias to fight shadow acne. Defaults to 0. */
|
|
22
|
+
bias?: number;
|
|
23
|
+
/** Normal-offset bias, softer fix for acne/peter-panning. Defaults to 0. */
|
|
24
|
+
normalBias?: number;
|
|
25
|
+
/** Near plane of the shadow camera. */
|
|
26
|
+
near?: number;
|
|
27
|
+
/** Far plane of the shadow camera. */
|
|
28
|
+
far?: number;
|
|
29
|
+
/**
|
|
30
|
+
* `directional` only: half-size of the orthographic frustum in world units —
|
|
31
|
+
* make it large enough to cover the area that should receive shadows.
|
|
32
|
+
*/
|
|
33
|
+
size?: number;
|
|
34
|
+
}
|
|
35
|
+
/** Shorthand: `true` for defaults, or a settings object. */
|
|
36
|
+
type ShadowConfig = boolean | LightShadow;
|
|
37
|
+
/**
|
|
38
|
+
* A light in the scene. Extensible via `type`; covers uniform fill (`ambient`,
|
|
39
|
+
* `hemisphere`), a sun-like source (`directional`), an omni source (`point`) and
|
|
40
|
+
* a cone spotlight (`spot`). Behavior (dimming, animation) is wired by `id` in
|
|
41
|
+
* the runtime through `ctx.lights` — the definition stays pure data.
|
|
42
|
+
*/
|
|
43
|
+
type Light = (LightBase & {
|
|
44
|
+
type: "ambient";
|
|
45
|
+
}) | (LightBase & {
|
|
46
|
+
type: "hemisphere"; /** Color bounced from below. Defaults to a dark gray. */
|
|
47
|
+
groundColor?: string;
|
|
48
|
+
}) | (LightBase & {
|
|
49
|
+
type: "directional"; /** World position the parallel rays emanate from. */
|
|
50
|
+
position: Vec3; /** Point the light aims at. Defaults to the origin. */
|
|
51
|
+
target?: Vec3; /** Cast shadows from this light. */
|
|
52
|
+
shadow?: ShadowConfig;
|
|
53
|
+
}) | (LightBase & {
|
|
54
|
+
type: "point"; /** World position of the source. */
|
|
55
|
+
position: Vec3; /** Range in world units; `0` (default) is infinite. */
|
|
56
|
+
distance?: number; /** Falloff exponent. Defaults to `2` (physically correct). */
|
|
57
|
+
decay?: number; /** Cast shadows from this light. */
|
|
58
|
+
shadow?: ShadowConfig;
|
|
59
|
+
}) | (LightBase & {
|
|
60
|
+
type: "spot"; /** World position of the source. */
|
|
61
|
+
position: Vec3; /** Point the cone aims at. Defaults to the origin. */
|
|
62
|
+
target?: Vec3; /** Cone half-angle in radians. */
|
|
63
|
+
angle?: number; /** Soft edge, `0`..`1`. Defaults to `0`. */
|
|
64
|
+
penumbra?: number; /** Range in world units; `0` (default) is infinite. */
|
|
65
|
+
distance?: number; /** Falloff exponent. Defaults to `2`. */
|
|
66
|
+
decay?: number; /** Cast shadows from this light. */
|
|
67
|
+
shadow?: ShadowConfig;
|
|
68
|
+
});
|
|
69
|
+
/** The discriminant values a `Light` can take. */
|
|
70
|
+
type LightType = Light["type"];
|
|
71
|
+
declare module "@scenography/scene" {
|
|
72
|
+
interface Scene {
|
|
73
|
+
/** Lights in the space — provided by `@scenography/plugin-light`. */
|
|
74
|
+
lights?: Light[];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/data/validate.d.ts
|
|
79
|
+
declare const validateLight: (light: Light) => ValidationResult;
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/data/plugin.d.ts
|
|
82
|
+
/** The data half of the light plugin: owns the `lights` scene key (a collection). */
|
|
83
|
+
declare const lightData: DataPlugin<Light>;
|
|
84
|
+
//#endregion
|
|
85
|
+
export { LightType as a, LightShadow as i, validateLight as n, Light as r, lightData as t };
|
|
86
|
+
//# sourceMappingURL=index-CfFuhLoP.d.mts.map
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_data = require("./data-CcMZWQIz.cjs");
|
|
3
|
+
let three = require("three");
|
|
4
|
+
//#region src/buildLight.ts
|
|
5
|
+
const DEFAULT_COLOR = "#ffffff";
|
|
6
|
+
const DEFAULT_SHADOW_MAP = 1024;
|
|
7
|
+
/** Enable and configure shadow casting on a light from its `shadow` data. */
|
|
8
|
+
const applyShadow = (light, config) => {
|
|
9
|
+
light.castShadow = true;
|
|
10
|
+
const s = typeof config === "object" ? config : {};
|
|
11
|
+
light.shadow.mapSize.setScalar(s.mapSize ?? DEFAULT_SHADOW_MAP);
|
|
12
|
+
if (s.bias !== void 0) light.shadow.bias = s.bias;
|
|
13
|
+
if (s.normalBias !== void 0) light.shadow.normalBias = s.normalBias;
|
|
14
|
+
const cam = light.shadow.camera;
|
|
15
|
+
if (s.near !== void 0) cam.near = s.near;
|
|
16
|
+
if (s.far !== void 0) cam.far = s.far;
|
|
17
|
+
if (cam instanceof three.OrthographicCamera && s.size !== void 0) {
|
|
18
|
+
cam.left = -s.size;
|
|
19
|
+
cam.right = s.size;
|
|
20
|
+
cam.top = s.size;
|
|
21
|
+
cam.bottom = -s.size;
|
|
22
|
+
}
|
|
23
|
+
cam.updateProjectionMatrix();
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Build the three.js object for a `Light`. Returns a `Group` (even for a single
|
|
27
|
+
* light) so directional/spot lights can carry their `target` in the same node,
|
|
28
|
+
* and so every light is addressed uniformly by `id` for reconciliation.
|
|
29
|
+
*/
|
|
30
|
+
function buildLight(light) {
|
|
31
|
+
const color = light.color ?? DEFAULT_COLOR;
|
|
32
|
+
const group = new three.Group();
|
|
33
|
+
switch (light.type) {
|
|
34
|
+
case "ambient":
|
|
35
|
+
group.add(new three.AmbientLight(color, light.intensity ?? 1.4));
|
|
36
|
+
break;
|
|
37
|
+
case "hemisphere":
|
|
38
|
+
group.add(new three.HemisphereLight(color, light.groundColor ?? "#444444", light.intensity ?? 1));
|
|
39
|
+
break;
|
|
40
|
+
case "directional": {
|
|
41
|
+
const l = new three.DirectionalLight(color, light.intensity ?? 1);
|
|
42
|
+
l.position.set(...light.position);
|
|
43
|
+
l.target.position.set(...light.target ?? [
|
|
44
|
+
0,
|
|
45
|
+
0,
|
|
46
|
+
0
|
|
47
|
+
]);
|
|
48
|
+
if (light.shadow) applyShadow(l, light.shadow);
|
|
49
|
+
group.add(l, l.target);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case "point": {
|
|
53
|
+
const l = new three.PointLight(color, light.intensity ?? 1, light.distance ?? 0, light.decay ?? 2);
|
|
54
|
+
l.position.set(...light.position);
|
|
55
|
+
if (light.shadow) applyShadow(l, light.shadow);
|
|
56
|
+
group.add(l);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case "spot": {
|
|
60
|
+
const l = new three.SpotLight(color, light.intensity ?? 1, light.distance ?? 0, light.angle ?? Math.PI / 6, light.penumbra ?? 0, light.decay ?? 2);
|
|
61
|
+
l.position.set(...light.position);
|
|
62
|
+
l.target.position.set(...light.target ?? [
|
|
63
|
+
0,
|
|
64
|
+
0,
|
|
65
|
+
0
|
|
66
|
+
]);
|
|
67
|
+
if (light.shadow) applyShadow(l, light.shadow);
|
|
68
|
+
group.add(l, l.target);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
group.name = `light:${light.id}`;
|
|
73
|
+
group.userData.scenographyId = light.id;
|
|
74
|
+
return group;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/LightController.ts
|
|
78
|
+
const isThreeLight = (o) => o.isLight === true;
|
|
79
|
+
/**
|
|
80
|
+
* High-level light control surfaced as `ctx.lights`. Works over the live light
|
|
81
|
+
* objects (queried fresh each call so it keeps working across hot-swaps),
|
|
82
|
+
* tweening intensity in the render loop.
|
|
83
|
+
*/
|
|
84
|
+
var LightController = class {
|
|
85
|
+
getLights;
|
|
86
|
+
tweens = /* @__PURE__ */ new Map();
|
|
87
|
+
/** Intensity captured before a dim, so `restore` can bring it back. */
|
|
88
|
+
baseline = /* @__PURE__ */ new WeakMap();
|
|
89
|
+
constructor(getLights) {
|
|
90
|
+
this.getLights = getLights;
|
|
91
|
+
}
|
|
92
|
+
lightsOf(group) {
|
|
93
|
+
const found = [];
|
|
94
|
+
group.traverse((o) => {
|
|
95
|
+
if (isThreeLight(o)) found.push(o);
|
|
96
|
+
});
|
|
97
|
+
return found;
|
|
98
|
+
}
|
|
99
|
+
all() {
|
|
100
|
+
return [...this.getLights().values()].flatMap((g) => this.lightsOf(g));
|
|
101
|
+
}
|
|
102
|
+
fade(light, to, duration) {
|
|
103
|
+
if (!duration || duration <= 0) {
|
|
104
|
+
this.tweens.delete(light);
|
|
105
|
+
light.intensity = to;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
this.tweens.set(light, {
|
|
109
|
+
from: light.intensity,
|
|
110
|
+
to,
|
|
111
|
+
elapsed: 0,
|
|
112
|
+
duration
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/** Set intensity and/or color of every light under `id`. */
|
|
116
|
+
set(id, props, opts = {}) {
|
|
117
|
+
const group = this.getLights().get(id);
|
|
118
|
+
if (!group) return;
|
|
119
|
+
for (const light of this.lightsOf(group)) {
|
|
120
|
+
if (props.color !== void 0) light.color.set(props.color);
|
|
121
|
+
if (props.intensity !== void 0) this.fade(light, props.intensity, opts.duration ?? 0);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Fade every light toward `factor` of its current intensity (default off). */
|
|
125
|
+
dimAll(opts = {}) {
|
|
126
|
+
const factor = opts.factor ?? 0;
|
|
127
|
+
for (const light of this.all()) {
|
|
128
|
+
const base = this.baseline.get(light) ?? light.intensity;
|
|
129
|
+
this.baseline.set(light, base);
|
|
130
|
+
this.fade(light, base * factor, opts.duration ?? 0);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Fade every light back to the intensity captured before the last dim. */
|
|
134
|
+
restore(opts = {}) {
|
|
135
|
+
for (const light of this.all()) {
|
|
136
|
+
const base = this.baseline.get(light);
|
|
137
|
+
if (base === void 0) continue;
|
|
138
|
+
this.fade(light, base, opts.duration ?? 0);
|
|
139
|
+
this.baseline.delete(light);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/** Advance active fades. Called once per frame with the frame delta in ms. */
|
|
143
|
+
update(deltaMs) {
|
|
144
|
+
for (const [light, t] of this.tweens) {
|
|
145
|
+
t.elapsed += deltaMs;
|
|
146
|
+
const k = t.duration > 0 ? Math.min(t.elapsed / t.duration, 1) : 1;
|
|
147
|
+
light.intensity = t.from + (t.to - t.from) * k;
|
|
148
|
+
if (k >= 1) this.tweens.delete(light);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region src/plugin.ts
|
|
154
|
+
/**
|
|
155
|
+
* The light plugin: builds each `Light` (ambient/hemisphere/directional/point/
|
|
156
|
+
* spot, with shadows) and exposes `ctx.lights` — a controller that dims/sets
|
|
157
|
+
* intensity and color over the live lights, tweening in the render loop.
|
|
158
|
+
*/
|
|
159
|
+
const light = () => ({
|
|
160
|
+
data: require_data.lightData,
|
|
161
|
+
build: (definition) => ({ object: buildLight(definition) }),
|
|
162
|
+
controller: (elements) => {
|
|
163
|
+
const controller = new LightController(elements);
|
|
164
|
+
return {
|
|
165
|
+
api: controller,
|
|
166
|
+
update: (deltaMs) => controller.update(deltaMs)
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
//#endregion
|
|
171
|
+
exports.LightController = LightController;
|
|
172
|
+
exports.buildLight = buildLight;
|
|
173
|
+
exports.light = light;
|
|
174
|
+
exports.lightData = require_data.lightData;
|
|
175
|
+
exports.validateLight = require_data.validateLight;
|
|
176
|
+
|
|
177
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["OrthographicCamera","Group","AmbientLight","HemisphereLight","DirectionalLight","PointLight","SpotLight","lightData"],"sources":["../src/buildLight.ts","../src/LightController.ts","../src/plugin.ts"],"sourcesContent":["import {\n AmbientLight,\n DirectionalLight,\n Group,\n HemisphereLight,\n OrthographicCamera,\n PointLight,\n SpotLight,\n type Object3D,\n} from \"three\";\nimport type { Light, LightShadow } from \"./data\";\n\nconst DEFAULT_COLOR = \"#ffffff\";\nconst DEFAULT_SHADOW_MAP = 1024;\n\n/** Enable and configure shadow casting on a light from its `shadow` data. */\nconst applyShadow = (\n light: DirectionalLight | SpotLight | PointLight,\n config: boolean | LightShadow,\n): void => {\n light.castShadow = true;\n const s: LightShadow = typeof config === \"object\" ? config : {};\n light.shadow.mapSize.setScalar(s.mapSize ?? DEFAULT_SHADOW_MAP);\n if (s.bias !== undefined) light.shadow.bias = s.bias;\n if (s.normalBias !== undefined) light.shadow.normalBias = s.normalBias;\n\n const cam = light.shadow.camera;\n if (s.near !== undefined) cam.near = s.near;\n if (s.far !== undefined) cam.far = s.far;\n // Directional lights use an orthographic frustum; size it to the lit area.\n if (cam instanceof OrthographicCamera && s.size !== undefined) {\n cam.left = -s.size;\n cam.right = s.size;\n cam.top = s.size;\n cam.bottom = -s.size;\n }\n cam.updateProjectionMatrix();\n};\n\n/**\n * Build the three.js object for a `Light`. Returns a `Group` (even for a single\n * light) so directional/spot lights can carry their `target` in the same node,\n * and so every light is addressed uniformly by `id` for reconciliation.\n */\nexport function buildLight(light: Light): Object3D {\n const color = light.color ?? DEFAULT_COLOR;\n const group = new Group();\n\n switch (light.type) {\n case \"ambient\":\n group.add(new AmbientLight(color, light.intensity ?? 1.4));\n break;\n case \"hemisphere\":\n group.add(\n new HemisphereLight(color, light.groundColor ?? \"#444444\", light.intensity ?? 1),\n );\n break;\n case \"directional\": {\n const l = new DirectionalLight(color, light.intensity ?? 1);\n l.position.set(...light.position);\n l.target.position.set(...(light.target ?? [0, 0, 0]));\n if (light.shadow) applyShadow(l, light.shadow);\n group.add(l, l.target);\n break;\n }\n case \"point\": {\n const l = new PointLight(color, light.intensity ?? 1, light.distance ?? 0, light.decay ?? 2);\n l.position.set(...light.position);\n if (light.shadow) applyShadow(l, light.shadow);\n group.add(l);\n break;\n }\n case \"spot\": {\n const l = new SpotLight(\n color,\n light.intensity ?? 1,\n light.distance ?? 0,\n light.angle ?? Math.PI / 6,\n light.penumbra ?? 0,\n light.decay ?? 2,\n );\n l.position.set(...light.position);\n l.target.position.set(...(light.target ?? [0, 0, 0]));\n if (light.shadow) applyShadow(l, light.shadow);\n group.add(l, l.target);\n break;\n }\n }\n\n group.name = `light:${light.id}`;\n group.userData.scenographyId = light.id;\n return group;\n}\n","import type { LightSet, LightSetOptions, LightsApi } from \"@scenography/engine\";\nimport type { Color, Light as ThreeLight, Object3D } from \"three\";\n\ninterface Tween {\n from: number;\n to: number;\n elapsed: number;\n duration: number;\n}\n\nconst isThreeLight = (o: Object3D): o is ThreeLight => (o as ThreeLight).isLight === true;\n\n/**\n * High-level light control surfaced as `ctx.lights`. Works over the live light\n * objects (queried fresh each call so it keeps working across hot-swaps),\n * tweening intensity in the render loop.\n */\nexport class LightController implements LightsApi {\n private readonly getLights: () => ReadonlyMap<string, Object3D>;\n private readonly tweens = new Map<ThreeLight, Tween>();\n /** Intensity captured before a dim, so `restore` can bring it back. */\n private readonly baseline = new WeakMap<ThreeLight, number>();\n\n constructor(getLights: () => ReadonlyMap<string, Object3D>) {\n this.getLights = getLights;\n }\n\n private lightsOf(group: Object3D): ThreeLight[] {\n const found: ThreeLight[] = [];\n group.traverse((o) => {\n if (isThreeLight(o)) found.push(o);\n });\n return found;\n }\n\n private all(): ThreeLight[] {\n return [...this.getLights().values()].flatMap((g) => this.lightsOf(g));\n }\n\n private fade(light: ThreeLight, to: number, duration: number): void {\n if (!duration || duration <= 0) {\n this.tweens.delete(light);\n light.intensity = to;\n return;\n }\n this.tweens.set(light, { from: light.intensity, to, elapsed: 0, duration });\n }\n\n /** Set intensity and/or color of every light under `id`. */\n set(id: string, props: LightSet, opts: LightSetOptions = {}): void {\n const group = this.getLights().get(id);\n if (!group) return;\n for (const light of this.lightsOf(group)) {\n if (props.color !== undefined) (light.color as Color).set(props.color);\n if (props.intensity !== undefined) this.fade(light, props.intensity, opts.duration ?? 0);\n }\n }\n\n /** Fade every light toward `factor` of its current intensity (default off). */\n dimAll(opts: LightSetOptions & { factor?: number } = {}): void {\n const factor = opts.factor ?? 0;\n for (const light of this.all()) {\n const base = this.baseline.get(light) ?? light.intensity;\n this.baseline.set(light, base);\n this.fade(light, base * factor, opts.duration ?? 0);\n }\n }\n\n /** Fade every light back to the intensity captured before the last dim. */\n restore(opts: LightSetOptions = {}): void {\n for (const light of this.all()) {\n const base = this.baseline.get(light);\n if (base === undefined) continue;\n this.fade(light, base, opts.duration ?? 0);\n this.baseline.delete(light);\n }\n }\n\n /** Advance active fades. Called once per frame with the frame delta in ms. */\n update(deltaMs: number): void {\n for (const [light, t] of this.tweens) {\n t.elapsed += deltaMs;\n const k = t.duration > 0 ? Math.min(t.elapsed / t.duration, 1) : 1;\n light.intensity = t.from + (t.to - t.from) * k;\n if (k >= 1) this.tweens.delete(light);\n }\n }\n}\n","import type { EnginePlugin } from \"@scenography/engine\";\n\nimport { buildLight } from \"./buildLight\";\nimport { LightController } from \"./LightController\";\nimport { lightData, type Light } from \"./data\";\n\n/**\n * The light plugin: builds each `Light` (ambient/hemisphere/directional/point/\n * spot, with shadows) and exposes `ctx.lights` — a controller that dims/sets\n * intensity and color over the live lights, tweening in the render loop.\n */\nexport const light = (): EnginePlugin<Light> => ({\n data: lightData,\n build: (definition) => ({ object: buildLight(definition) }),\n controller: (elements) => {\n const controller = new LightController(elements);\n return { api: controller, update: (deltaMs) => controller.update(deltaMs) };\n },\n});\n"],"mappings":"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"}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { a as LightType, i as LightShadow, n as validateLight, r as Light, t as lightData } from "./index-CfFuhLoP.cjs";
|
|
2
|
+
import { EnginePlugin, LightSet, LightSetOptions, LightsApi } from "@scenography/engine";
|
|
3
|
+
import { Object3D } from "three";
|
|
4
|
+
|
|
5
|
+
//#region src/plugin.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* The light plugin: builds each `Light` (ambient/hemisphere/directional/point/
|
|
8
|
+
* spot, with shadows) and exposes `ctx.lights` — a controller that dims/sets
|
|
9
|
+
* intensity and color over the live lights, tweening in the render loop.
|
|
10
|
+
*/
|
|
11
|
+
declare const light: () => EnginePlugin<Light>;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/buildLight.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* Build the three.js object for a `Light`. Returns a `Group` (even for a single
|
|
16
|
+
* light) so directional/spot lights can carry their `target` in the same node,
|
|
17
|
+
* and so every light is addressed uniformly by `id` for reconciliation.
|
|
18
|
+
*/
|
|
19
|
+
declare function buildLight(light: Light): Object3D;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/LightController.d.ts
|
|
22
|
+
/**
|
|
23
|
+
* High-level light control surfaced as `ctx.lights`. Works over the live light
|
|
24
|
+
* objects (queried fresh each call so it keeps working across hot-swaps),
|
|
25
|
+
* tweening intensity in the render loop.
|
|
26
|
+
*/
|
|
27
|
+
declare class LightController implements LightsApi {
|
|
28
|
+
private readonly getLights;
|
|
29
|
+
private readonly tweens;
|
|
30
|
+
/** Intensity captured before a dim, so `restore` can bring it back. */
|
|
31
|
+
private readonly baseline;
|
|
32
|
+
constructor(getLights: () => ReadonlyMap<string, Object3D>);
|
|
33
|
+
private lightsOf;
|
|
34
|
+
private all;
|
|
35
|
+
private fade;
|
|
36
|
+
/** Set intensity and/or color of every light under `id`. */
|
|
37
|
+
set(id: string, props: LightSet, opts?: LightSetOptions): void;
|
|
38
|
+
/** Fade every light toward `factor` of its current intensity (default off). */
|
|
39
|
+
dimAll(opts?: LightSetOptions & {
|
|
40
|
+
factor?: number;
|
|
41
|
+
}): void;
|
|
42
|
+
/** Fade every light back to the intensity captured before the last dim. */
|
|
43
|
+
restore(opts?: LightSetOptions): void;
|
|
44
|
+
/** Advance active fades. Called once per frame with the frame delta in ms. */
|
|
45
|
+
update(deltaMs: number): void;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { type Light, LightController, type LightShadow, type LightType, buildLight, light, lightData, validateLight };
|
|
49
|
+
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { a as LightType, i as LightShadow, n as validateLight, r as Light, t as lightData } from "./index-CfFuhLoP.mjs";
|
|
2
|
+
import { Object3D } from "three";
|
|
3
|
+
import { EnginePlugin, LightSet, LightSetOptions, LightsApi } from "@scenography/engine";
|
|
4
|
+
|
|
5
|
+
//#region src/plugin.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* The light plugin: builds each `Light` (ambient/hemisphere/directional/point/
|
|
8
|
+
* spot, with shadows) and exposes `ctx.lights` — a controller that dims/sets
|
|
9
|
+
* intensity and color over the live lights, tweening in the render loop.
|
|
10
|
+
*/
|
|
11
|
+
declare const light: () => EnginePlugin<Light>;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/buildLight.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* Build the three.js object for a `Light`. Returns a `Group` (even for a single
|
|
16
|
+
* light) so directional/spot lights can carry their `target` in the same node,
|
|
17
|
+
* and so every light is addressed uniformly by `id` for reconciliation.
|
|
18
|
+
*/
|
|
19
|
+
declare function buildLight(light: Light): Object3D;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/LightController.d.ts
|
|
22
|
+
/**
|
|
23
|
+
* High-level light control surfaced as `ctx.lights`. Works over the live light
|
|
24
|
+
* objects (queried fresh each call so it keeps working across hot-swaps),
|
|
25
|
+
* tweening intensity in the render loop.
|
|
26
|
+
*/
|
|
27
|
+
declare class LightController implements LightsApi {
|
|
28
|
+
private readonly getLights;
|
|
29
|
+
private readonly tweens;
|
|
30
|
+
/** Intensity captured before a dim, so `restore` can bring it back. */
|
|
31
|
+
private readonly baseline;
|
|
32
|
+
constructor(getLights: () => ReadonlyMap<string, Object3D>);
|
|
33
|
+
private lightsOf;
|
|
34
|
+
private all;
|
|
35
|
+
private fade;
|
|
36
|
+
/** Set intensity and/or color of every light under `id`. */
|
|
37
|
+
set(id: string, props: LightSet, opts?: LightSetOptions): void;
|
|
38
|
+
/** Fade every light toward `factor` of its current intensity (default off). */
|
|
39
|
+
dimAll(opts?: LightSetOptions & {
|
|
40
|
+
factor?: number;
|
|
41
|
+
}): void;
|
|
42
|
+
/** Fade every light back to the intensity captured before the last dim. */
|
|
43
|
+
restore(opts?: LightSetOptions): void;
|
|
44
|
+
/** Advance active fades. Called once per frame with the frame delta in ms. */
|
|
45
|
+
update(deltaMs: number): void;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { type Light, LightController, type LightShadow, type LightType, buildLight, light, lightData, validateLight };
|
|
49
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { n as validateLight, t as lightData } from "./data-bkULec9x.mjs";
|
|
2
|
+
import { AmbientLight, DirectionalLight, Group, HemisphereLight, OrthographicCamera, PointLight, SpotLight } from "three";
|
|
3
|
+
//#region src/buildLight.ts
|
|
4
|
+
const DEFAULT_COLOR = "#ffffff";
|
|
5
|
+
const DEFAULT_SHADOW_MAP = 1024;
|
|
6
|
+
/** Enable and configure shadow casting on a light from its `shadow` data. */
|
|
7
|
+
const applyShadow = (light, config) => {
|
|
8
|
+
light.castShadow = true;
|
|
9
|
+
const s = typeof config === "object" ? config : {};
|
|
10
|
+
light.shadow.mapSize.setScalar(s.mapSize ?? DEFAULT_SHADOW_MAP);
|
|
11
|
+
if (s.bias !== void 0) light.shadow.bias = s.bias;
|
|
12
|
+
if (s.normalBias !== void 0) light.shadow.normalBias = s.normalBias;
|
|
13
|
+
const cam = light.shadow.camera;
|
|
14
|
+
if (s.near !== void 0) cam.near = s.near;
|
|
15
|
+
if (s.far !== void 0) cam.far = s.far;
|
|
16
|
+
if (cam instanceof OrthographicCamera && s.size !== void 0) {
|
|
17
|
+
cam.left = -s.size;
|
|
18
|
+
cam.right = s.size;
|
|
19
|
+
cam.top = s.size;
|
|
20
|
+
cam.bottom = -s.size;
|
|
21
|
+
}
|
|
22
|
+
cam.updateProjectionMatrix();
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Build the three.js object for a `Light`. Returns a `Group` (even for a single
|
|
26
|
+
* light) so directional/spot lights can carry their `target` in the same node,
|
|
27
|
+
* and so every light is addressed uniformly by `id` for reconciliation.
|
|
28
|
+
*/
|
|
29
|
+
function buildLight(light) {
|
|
30
|
+
const color = light.color ?? DEFAULT_COLOR;
|
|
31
|
+
const group = new Group();
|
|
32
|
+
switch (light.type) {
|
|
33
|
+
case "ambient":
|
|
34
|
+
group.add(new AmbientLight(color, light.intensity ?? 1.4));
|
|
35
|
+
break;
|
|
36
|
+
case "hemisphere":
|
|
37
|
+
group.add(new HemisphereLight(color, light.groundColor ?? "#444444", light.intensity ?? 1));
|
|
38
|
+
break;
|
|
39
|
+
case "directional": {
|
|
40
|
+
const l = new DirectionalLight(color, light.intensity ?? 1);
|
|
41
|
+
l.position.set(...light.position);
|
|
42
|
+
l.target.position.set(...light.target ?? [
|
|
43
|
+
0,
|
|
44
|
+
0,
|
|
45
|
+
0
|
|
46
|
+
]);
|
|
47
|
+
if (light.shadow) applyShadow(l, light.shadow);
|
|
48
|
+
group.add(l, l.target);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case "point": {
|
|
52
|
+
const l = new PointLight(color, light.intensity ?? 1, light.distance ?? 0, light.decay ?? 2);
|
|
53
|
+
l.position.set(...light.position);
|
|
54
|
+
if (light.shadow) applyShadow(l, light.shadow);
|
|
55
|
+
group.add(l);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case "spot": {
|
|
59
|
+
const l = new SpotLight(color, light.intensity ?? 1, light.distance ?? 0, light.angle ?? Math.PI / 6, light.penumbra ?? 0, light.decay ?? 2);
|
|
60
|
+
l.position.set(...light.position);
|
|
61
|
+
l.target.position.set(...light.target ?? [
|
|
62
|
+
0,
|
|
63
|
+
0,
|
|
64
|
+
0
|
|
65
|
+
]);
|
|
66
|
+
if (light.shadow) applyShadow(l, light.shadow);
|
|
67
|
+
group.add(l, l.target);
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
group.name = `light:${light.id}`;
|
|
72
|
+
group.userData.scenographyId = light.id;
|
|
73
|
+
return group;
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/LightController.ts
|
|
77
|
+
const isThreeLight = (o) => o.isLight === true;
|
|
78
|
+
/**
|
|
79
|
+
* High-level light control surfaced as `ctx.lights`. Works over the live light
|
|
80
|
+
* objects (queried fresh each call so it keeps working across hot-swaps),
|
|
81
|
+
* tweening intensity in the render loop.
|
|
82
|
+
*/
|
|
83
|
+
var LightController = class {
|
|
84
|
+
getLights;
|
|
85
|
+
tweens = /* @__PURE__ */ new Map();
|
|
86
|
+
/** Intensity captured before a dim, so `restore` can bring it back. */
|
|
87
|
+
baseline = /* @__PURE__ */ new WeakMap();
|
|
88
|
+
constructor(getLights) {
|
|
89
|
+
this.getLights = getLights;
|
|
90
|
+
}
|
|
91
|
+
lightsOf(group) {
|
|
92
|
+
const found = [];
|
|
93
|
+
group.traverse((o) => {
|
|
94
|
+
if (isThreeLight(o)) found.push(o);
|
|
95
|
+
});
|
|
96
|
+
return found;
|
|
97
|
+
}
|
|
98
|
+
all() {
|
|
99
|
+
return [...this.getLights().values()].flatMap((g) => this.lightsOf(g));
|
|
100
|
+
}
|
|
101
|
+
fade(light, to, duration) {
|
|
102
|
+
if (!duration || duration <= 0) {
|
|
103
|
+
this.tweens.delete(light);
|
|
104
|
+
light.intensity = to;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.tweens.set(light, {
|
|
108
|
+
from: light.intensity,
|
|
109
|
+
to,
|
|
110
|
+
elapsed: 0,
|
|
111
|
+
duration
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/** Set intensity and/or color of every light under `id`. */
|
|
115
|
+
set(id, props, opts = {}) {
|
|
116
|
+
const group = this.getLights().get(id);
|
|
117
|
+
if (!group) return;
|
|
118
|
+
for (const light of this.lightsOf(group)) {
|
|
119
|
+
if (props.color !== void 0) light.color.set(props.color);
|
|
120
|
+
if (props.intensity !== void 0) this.fade(light, props.intensity, opts.duration ?? 0);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Fade every light toward `factor` of its current intensity (default off). */
|
|
124
|
+
dimAll(opts = {}) {
|
|
125
|
+
const factor = opts.factor ?? 0;
|
|
126
|
+
for (const light of this.all()) {
|
|
127
|
+
const base = this.baseline.get(light) ?? light.intensity;
|
|
128
|
+
this.baseline.set(light, base);
|
|
129
|
+
this.fade(light, base * factor, opts.duration ?? 0);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** Fade every light back to the intensity captured before the last dim. */
|
|
133
|
+
restore(opts = {}) {
|
|
134
|
+
for (const light of this.all()) {
|
|
135
|
+
const base = this.baseline.get(light);
|
|
136
|
+
if (base === void 0) continue;
|
|
137
|
+
this.fade(light, base, opts.duration ?? 0);
|
|
138
|
+
this.baseline.delete(light);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** Advance active fades. Called once per frame with the frame delta in ms. */
|
|
142
|
+
update(deltaMs) {
|
|
143
|
+
for (const [light, t] of this.tweens) {
|
|
144
|
+
t.elapsed += deltaMs;
|
|
145
|
+
const k = t.duration > 0 ? Math.min(t.elapsed / t.duration, 1) : 1;
|
|
146
|
+
light.intensity = t.from + (t.to - t.from) * k;
|
|
147
|
+
if (k >= 1) this.tweens.delete(light);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/plugin.ts
|
|
153
|
+
/**
|
|
154
|
+
* The light plugin: builds each `Light` (ambient/hemisphere/directional/point/
|
|
155
|
+
* spot, with shadows) and exposes `ctx.lights` — a controller that dims/sets
|
|
156
|
+
* intensity and color over the live lights, tweening in the render loop.
|
|
157
|
+
*/
|
|
158
|
+
const light = () => ({
|
|
159
|
+
data: lightData,
|
|
160
|
+
build: (definition) => ({ object: buildLight(definition) }),
|
|
161
|
+
controller: (elements) => {
|
|
162
|
+
const controller = new LightController(elements);
|
|
163
|
+
return {
|
|
164
|
+
api: controller,
|
|
165
|
+
update: (deltaMs) => controller.update(deltaMs)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
//#endregion
|
|
170
|
+
export { LightController, buildLight, light, lightData, validateLight };
|
|
171
|
+
|
|
172
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/buildLight.ts","../src/LightController.ts","../src/plugin.ts"],"sourcesContent":["import {\n AmbientLight,\n DirectionalLight,\n Group,\n HemisphereLight,\n OrthographicCamera,\n PointLight,\n SpotLight,\n type Object3D,\n} from \"three\";\nimport type { Light, LightShadow } from \"./data\";\n\nconst DEFAULT_COLOR = \"#ffffff\";\nconst DEFAULT_SHADOW_MAP = 1024;\n\n/** Enable and configure shadow casting on a light from its `shadow` data. */\nconst applyShadow = (\n light: DirectionalLight | SpotLight | PointLight,\n config: boolean | LightShadow,\n): void => {\n light.castShadow = true;\n const s: LightShadow = typeof config === \"object\" ? config : {};\n light.shadow.mapSize.setScalar(s.mapSize ?? DEFAULT_SHADOW_MAP);\n if (s.bias !== undefined) light.shadow.bias = s.bias;\n if (s.normalBias !== undefined) light.shadow.normalBias = s.normalBias;\n\n const cam = light.shadow.camera;\n if (s.near !== undefined) cam.near = s.near;\n if (s.far !== undefined) cam.far = s.far;\n // Directional lights use an orthographic frustum; size it to the lit area.\n if (cam instanceof OrthographicCamera && s.size !== undefined) {\n cam.left = -s.size;\n cam.right = s.size;\n cam.top = s.size;\n cam.bottom = -s.size;\n }\n cam.updateProjectionMatrix();\n};\n\n/**\n * Build the three.js object for a `Light`. Returns a `Group` (even for a single\n * light) so directional/spot lights can carry their `target` in the same node,\n * and so every light is addressed uniformly by `id` for reconciliation.\n */\nexport function buildLight(light: Light): Object3D {\n const color = light.color ?? DEFAULT_COLOR;\n const group = new Group();\n\n switch (light.type) {\n case \"ambient\":\n group.add(new AmbientLight(color, light.intensity ?? 1.4));\n break;\n case \"hemisphere\":\n group.add(\n new HemisphereLight(color, light.groundColor ?? \"#444444\", light.intensity ?? 1),\n );\n break;\n case \"directional\": {\n const l = new DirectionalLight(color, light.intensity ?? 1);\n l.position.set(...light.position);\n l.target.position.set(...(light.target ?? [0, 0, 0]));\n if (light.shadow) applyShadow(l, light.shadow);\n group.add(l, l.target);\n break;\n }\n case \"point\": {\n const l = new PointLight(color, light.intensity ?? 1, light.distance ?? 0, light.decay ?? 2);\n l.position.set(...light.position);\n if (light.shadow) applyShadow(l, light.shadow);\n group.add(l);\n break;\n }\n case \"spot\": {\n const l = new SpotLight(\n color,\n light.intensity ?? 1,\n light.distance ?? 0,\n light.angle ?? Math.PI / 6,\n light.penumbra ?? 0,\n light.decay ?? 2,\n );\n l.position.set(...light.position);\n l.target.position.set(...(light.target ?? [0, 0, 0]));\n if (light.shadow) applyShadow(l, light.shadow);\n group.add(l, l.target);\n break;\n }\n }\n\n group.name = `light:${light.id}`;\n group.userData.scenographyId = light.id;\n return group;\n}\n","import type { LightSet, LightSetOptions, LightsApi } from \"@scenography/engine\";\nimport type { Color, Light as ThreeLight, Object3D } from \"three\";\n\ninterface Tween {\n from: number;\n to: number;\n elapsed: number;\n duration: number;\n}\n\nconst isThreeLight = (o: Object3D): o is ThreeLight => (o as ThreeLight).isLight === true;\n\n/**\n * High-level light control surfaced as `ctx.lights`. Works over the live light\n * objects (queried fresh each call so it keeps working across hot-swaps),\n * tweening intensity in the render loop.\n */\nexport class LightController implements LightsApi {\n private readonly getLights: () => ReadonlyMap<string, Object3D>;\n private readonly tweens = new Map<ThreeLight, Tween>();\n /** Intensity captured before a dim, so `restore` can bring it back. */\n private readonly baseline = new WeakMap<ThreeLight, number>();\n\n constructor(getLights: () => ReadonlyMap<string, Object3D>) {\n this.getLights = getLights;\n }\n\n private lightsOf(group: Object3D): ThreeLight[] {\n const found: ThreeLight[] = [];\n group.traverse((o) => {\n if (isThreeLight(o)) found.push(o);\n });\n return found;\n }\n\n private all(): ThreeLight[] {\n return [...this.getLights().values()].flatMap((g) => this.lightsOf(g));\n }\n\n private fade(light: ThreeLight, to: number, duration: number): void {\n if (!duration || duration <= 0) {\n this.tweens.delete(light);\n light.intensity = to;\n return;\n }\n this.tweens.set(light, { from: light.intensity, to, elapsed: 0, duration });\n }\n\n /** Set intensity and/or color of every light under `id`. */\n set(id: string, props: LightSet, opts: LightSetOptions = {}): void {\n const group = this.getLights().get(id);\n if (!group) return;\n for (const light of this.lightsOf(group)) {\n if (props.color !== undefined) (light.color as Color).set(props.color);\n if (props.intensity !== undefined) this.fade(light, props.intensity, opts.duration ?? 0);\n }\n }\n\n /** Fade every light toward `factor` of its current intensity (default off). */\n dimAll(opts: LightSetOptions & { factor?: number } = {}): void {\n const factor = opts.factor ?? 0;\n for (const light of this.all()) {\n const base = this.baseline.get(light) ?? light.intensity;\n this.baseline.set(light, base);\n this.fade(light, base * factor, opts.duration ?? 0);\n }\n }\n\n /** Fade every light back to the intensity captured before the last dim. */\n restore(opts: LightSetOptions = {}): void {\n for (const light of this.all()) {\n const base = this.baseline.get(light);\n if (base === undefined) continue;\n this.fade(light, base, opts.duration ?? 0);\n this.baseline.delete(light);\n }\n }\n\n /** Advance active fades. Called once per frame with the frame delta in ms. */\n update(deltaMs: number): void {\n for (const [light, t] of this.tweens) {\n t.elapsed += deltaMs;\n const k = t.duration > 0 ? Math.min(t.elapsed / t.duration, 1) : 1;\n light.intensity = t.from + (t.to - t.from) * k;\n if (k >= 1) this.tweens.delete(light);\n }\n }\n}\n","import type { EnginePlugin } from \"@scenography/engine\";\n\nimport { buildLight } from \"./buildLight\";\nimport { LightController } from \"./LightController\";\nimport { lightData, type Light } from \"./data\";\n\n/**\n * The light plugin: builds each `Light` (ambient/hemisphere/directional/point/\n * spot, with shadows) and exposes `ctx.lights` — a controller that dims/sets\n * intensity and color over the live lights, tweening in the render loop.\n */\nexport const light = (): EnginePlugin<Light> => ({\n data: lightData,\n build: (definition) => ({ object: buildLight(definition) }),\n controller: (elements) => {\n const controller = new LightController(elements);\n return { api: controller, update: (deltaMs) => controller.update(deltaMs) };\n },\n});\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@scenography/plugin-light",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Light plugin for scenography: ambient/hemisphere/directional/point/spot lights with shadows, and ctx.lights runtime control.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "./dist/index.cjs",
|
|
11
|
+
"module": "./dist/index.mjs",
|
|
12
|
+
"types": "./dist/index.d.cts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": {
|
|
16
|
+
"types": "./dist/index.d.mts",
|
|
17
|
+
"default": "./dist/index.mjs"
|
|
18
|
+
},
|
|
19
|
+
"require": {
|
|
20
|
+
"types": "./dist/index.d.cts",
|
|
21
|
+
"default": "./dist/index.cjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"./data": {
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./dist/data.d.mts",
|
|
27
|
+
"default": "./dist/data.mjs"
|
|
28
|
+
},
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./dist/data.d.cts",
|
|
31
|
+
"default": "./dist/data.cjs"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@scenography/scene": "0.2.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/three": "^0.160.0",
|
|
40
|
+
"three": "^0.160.0",
|
|
41
|
+
"@scenography/engine": "0.2.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"three": ">=0.160.0",
|
|
45
|
+
"@scenography/engine": "0.2.0"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsdown",
|
|
49
|
+
"dev": "tsdown --watch",
|
|
50
|
+
"typecheck": "tsc --noEmit"
|
|
51
|
+
}
|
|
52
|
+
}
|