@aura3d/scene 1.0.6
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 +17 -0
- package/dist/Bounds.d.ts +18 -0
- package/dist/Bounds.d.ts.map +1 -0
- package/dist/Bounds.js +55 -0
- package/dist/Bounds.js.map +1 -0
- package/dist/Camera.d.ts +22 -0
- package/dist/Camera.d.ts.map +1 -0
- package/dist/Camera.js +44 -0
- package/dist/Camera.js.map +1 -0
- package/dist/DirectionalLight.d.ts +7 -0
- package/dist/DirectionalLight.d.ts.map +1 -0
- package/dist/DirectionalLight.js +12 -0
- package/dist/DirectionalLight.js.map +1 -0
- package/dist/Hierarchy.d.ts +6 -0
- package/dist/Hierarchy.d.ts.map +1 -0
- package/dist/Hierarchy.js +19 -0
- package/dist/Hierarchy.js.map +1 -0
- package/dist/Layers.d.ts +8 -0
- package/dist/Layers.d.ts.map +1 -0
- package/dist/Layers.js +21 -0
- package/dist/Layers.js.map +1 -0
- package/dist/Light.d.ts +14 -0
- package/dist/Light.d.ts.map +1 -0
- package/dist/Light.js +23 -0
- package/dist/Light.js.map +1 -0
- package/dist/Lights.d.ts +6 -0
- package/dist/Lights.d.ts.map +1 -0
- package/dist/Lights.js +5 -0
- package/dist/Lights.js.map +1 -0
- package/dist/MathTypes.d.ts +52 -0
- package/dist/MathTypes.d.ts.map +1 -0
- package/dist/MathTypes.js +119 -0
- package/dist/MathTypes.js.map +1 -0
- package/dist/Object3D.d.ts +48 -0
- package/dist/Object3D.d.ts.map +1 -0
- package/dist/Object3D.js +122 -0
- package/dist/Object3D.js.map +1 -0
- package/dist/OrthographicCamera.d.ts +29 -0
- package/dist/OrthographicCamera.d.ts.map +1 -0
- package/dist/OrthographicCamera.js +59 -0
- package/dist/OrthographicCamera.js.map +1 -0
- package/dist/PerspectiveCamera.d.ts +20 -0
- package/dist/PerspectiveCamera.d.ts.map +1 -0
- package/dist/PerspectiveCamera.js +42 -0
- package/dist/PerspectiveCamera.js.map +1 -0
- package/dist/PointLight.d.ts +10 -0
- package/dist/PointLight.d.ts.map +1 -0
- package/dist/PointLight.js +22 -0
- package/dist/PointLight.js.map +1 -0
- package/dist/Renderable.d.ts +30 -0
- package/dist/Renderable.d.ts.map +1 -0
- package/dist/Renderable.js +54 -0
- package/dist/Renderable.js.map +1 -0
- package/dist/Scene.d.ts +45 -0
- package/dist/Scene.d.ts.map +1 -0
- package/dist/Scene.js +117 -0
- package/dist/Scene.js.map +1 -0
- package/dist/SceneMetadata.d.ts +79 -0
- package/dist/SceneMetadata.d.ts.map +1 -0
- package/dist/SceneMetadata.js +130 -0
- package/dist/SceneMetadata.js.map +1 -0
- package/dist/SceneNode.d.ts +42 -0
- package/dist/SceneNode.d.ts.map +1 -0
- package/dist/SceneNode.js +126 -0
- package/dist/SceneNode.js.map +1 -0
- package/dist/SceneQuery.d.ts +16 -0
- package/dist/SceneQuery.d.ts.map +1 -0
- package/dist/SceneQuery.js +37 -0
- package/dist/SceneQuery.js.map +1 -0
- package/dist/SceneSerializer.d.ts +59 -0
- package/dist/SceneSerializer.d.ts.map +1 -0
- package/dist/SceneSerializer.js +127 -0
- package/dist/SceneSerializer.js.map +1 -0
- package/dist/SpotLight.d.ts +14 -0
- package/dist/SpotLight.d.ts.map +1 -0
- package/dist/SpotLight.js +35 -0
- package/dist/SpotLight.js.map +1 -0
- package/dist/TransformNode.d.ts +26 -0
- package/dist/TransformNode.d.ts.map +1 -0
- package/dist/TransformNode.js +98 -0
- package/dist/TransformNode.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/package.json +18 -0
- package/src/Bounds.ts +68 -0
- package/src/Camera.ts +56 -0
- package/src/DirectionalLight.ts +13 -0
- package/src/Hierarchy.ts +20 -0
- package/src/Layers.ts +24 -0
- package/src/Light.ts +27 -0
- package/src/Lights.ts +5 -0
- package/src/MathTypes.ts +157 -0
- package/src/Object3D.ts +149 -0
- package/src/OrthographicCamera.ts +73 -0
- package/src/PerspectiveCamera.ts +54 -0
- package/src/PointLight.ts +25 -0
- package/src/Renderable.ts +71 -0
- package/src/Scene.ts +134 -0
- package/src/SceneMetadata.ts +225 -0
- package/src/SceneNode.ts +139 -0
- package/src/SceneQuery.ts +39 -0
- package/src/SceneSerializer.ts +177 -0
- package/src/SpotLight.ts +39 -0
- package/src/TransformNode.ts +116 -0
- package/src/index.ts +20 -0
- package/tests/scene.test.ts +117 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { ValidationError } from "@aura3d/core";
|
|
2
|
+
import { DirectionalLight } from "./DirectionalLight.js";
|
|
3
|
+
import { OrthographicCamera } from "./OrthographicCamera.js";
|
|
4
|
+
import { PerspectiveCamera } from "./PerspectiveCamera.js";
|
|
5
|
+
import { PointLight } from "./PointLight.js";
|
|
6
|
+
import { Renderable } from "./Renderable.js";
|
|
7
|
+
import { Scene } from "./Scene.js";
|
|
8
|
+
import { SceneNode } from "./SceneNode.js";
|
|
9
|
+
import { SpotLight } from "./SpotLight.js";
|
|
10
|
+
export function serializeScene(scene) {
|
|
11
|
+
return {
|
|
12
|
+
version: 1,
|
|
13
|
+
...(scene.metadata.isEmpty ? {} : { metadata: scene.metadata.toJSON() }),
|
|
14
|
+
root: serializeNode(scene.root)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function deserializeScene(serialized) {
|
|
18
|
+
if (serialized.version !== 1)
|
|
19
|
+
throw new ValidationError("SCENE_VERSION", `Unsupported scene version: ${serialized.version}`);
|
|
20
|
+
const scene = new Scene();
|
|
21
|
+
if (serialized.metadata)
|
|
22
|
+
scene.metadata.replace(serialized.metadata);
|
|
23
|
+
for (const child of serialized.root.children) {
|
|
24
|
+
const node = deserializeNode(child);
|
|
25
|
+
scene.root.addChild(node);
|
|
26
|
+
scene.registerSubtree(node);
|
|
27
|
+
}
|
|
28
|
+
return scene;
|
|
29
|
+
}
|
|
30
|
+
function serializeNode(node) {
|
|
31
|
+
const renderable = node.renderable;
|
|
32
|
+
return {
|
|
33
|
+
id: node.id,
|
|
34
|
+
name: node.name,
|
|
35
|
+
visible: node.visible,
|
|
36
|
+
layerMask: node.layerMask,
|
|
37
|
+
kind: node instanceof PerspectiveCamera ? "perspectiveCamera" : node instanceof OrthographicCamera ? "orthographicCamera" : node instanceof DirectionalLight ? "directionalLight" : node instanceof PointLight ? "pointLight" : node instanceof SpotLight ? "spotLight" : "node",
|
|
38
|
+
transform: {
|
|
39
|
+
position: [...node.transform.position],
|
|
40
|
+
rotation: [...node.transform.rotation],
|
|
41
|
+
scale: [...node.transform.scale]
|
|
42
|
+
},
|
|
43
|
+
renderable: renderable ? {
|
|
44
|
+
geometry: renderable.geometry,
|
|
45
|
+
material: renderable.material,
|
|
46
|
+
layerMask: renderable.layerMask,
|
|
47
|
+
castShadow: renderable.castShadow,
|
|
48
|
+
receiveShadow: renderable.receiveShadow,
|
|
49
|
+
...(renderable.morphWeights.length > 0 ? { morphWeights: [...renderable.morphWeights] } : {}),
|
|
50
|
+
...(renderable.instanceTransforms ? { instanceTransforms: [...renderable.instanceTransforms] } : {}),
|
|
51
|
+
...(renderable.instanceColors ? { instanceColors: [...renderable.instanceColors] } : {})
|
|
52
|
+
} : undefined,
|
|
53
|
+
camera: serializeCamera(node),
|
|
54
|
+
light: serializeLight(node),
|
|
55
|
+
children: node.children.map(serializeNode)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function deserializeNode(data) {
|
|
59
|
+
const node = data.kind === "perspectiveCamera" ? new PerspectiveCamera({ id: data.id, name: data.name, fovYRadians: data.camera?.fovYRadians, aspect: data.camera?.aspect, near: data.camera?.near, far: data.camera?.far }) :
|
|
60
|
+
data.kind === "orthographicCamera" ? new OrthographicCamera({ id: data.id, name: data.name, left: data.camera?.left, right: data.camera?.right, bottom: data.camera?.bottom, top: data.camera?.top, near: data.camera?.near, far: data.camera?.far, zoom: data.camera?.zoom, resizeMode: data.camera?.resizeMode }) :
|
|
61
|
+
data.kind === "directionalLight" ? new DirectionalLight(data.name, data.id) :
|
|
62
|
+
data.kind === "pointLight" ? new PointLight(data.name, data.id) :
|
|
63
|
+
data.kind === "spotLight" ? new SpotLight(data.name, data.id) :
|
|
64
|
+
new SceneNode({ id: data.id, name: data.name });
|
|
65
|
+
node.visible = data.visible;
|
|
66
|
+
node.layerMask = data.layerMask;
|
|
67
|
+
node.transform.setPosition(...data.transform.position);
|
|
68
|
+
node.transform.setRotation(...data.transform.rotation);
|
|
69
|
+
node.transform.setScale(...data.transform.scale);
|
|
70
|
+
if (data.camera && (node instanceof PerspectiveCamera || node instanceof OrthographicCamera))
|
|
71
|
+
node.setViewport(data.camera.viewport);
|
|
72
|
+
if (data.light && (node instanceof DirectionalLight || node instanceof PointLight || node instanceof SpotLight)) {
|
|
73
|
+
node.color = [...data.light.color];
|
|
74
|
+
node.intensity = data.light.intensity;
|
|
75
|
+
node.castsShadow = data.light.castsShadow;
|
|
76
|
+
}
|
|
77
|
+
if (data.light?.range !== undefined && (node instanceof PointLight || node instanceof SpotLight))
|
|
78
|
+
node.range = data.light.range;
|
|
79
|
+
if (data.light?.angle !== undefined && node instanceof SpotLight)
|
|
80
|
+
node.angle = data.light.angle;
|
|
81
|
+
if (data.light?.penumbra !== undefined && node instanceof SpotLight)
|
|
82
|
+
node.penumbra = data.light.penumbra;
|
|
83
|
+
if (data.renderable)
|
|
84
|
+
node.renderable = new Renderable(data.renderable);
|
|
85
|
+
for (const child of data.children)
|
|
86
|
+
node.addChild(deserializeNode(child));
|
|
87
|
+
return node;
|
|
88
|
+
}
|
|
89
|
+
function serializeCamera(node) {
|
|
90
|
+
if (node instanceof PerspectiveCamera) {
|
|
91
|
+
return {
|
|
92
|
+
fovYRadians: node.fovYRadians,
|
|
93
|
+
aspect: node.aspect,
|
|
94
|
+
near: node.near,
|
|
95
|
+
far: node.far,
|
|
96
|
+
viewport: { ...node.viewport }
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
if (node instanceof OrthographicCamera) {
|
|
100
|
+
return {
|
|
101
|
+
left: node.left,
|
|
102
|
+
right: node.right,
|
|
103
|
+
bottom: node.bottom,
|
|
104
|
+
top: node.top,
|
|
105
|
+
near: node.near,
|
|
106
|
+
far: node.far,
|
|
107
|
+
zoom: node.zoom,
|
|
108
|
+
resizeMode: node.resizeMode,
|
|
109
|
+
viewport: { ...node.viewport }
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
function serializeLight(node) {
|
|
115
|
+
if (node instanceof DirectionalLight || node instanceof PointLight || node instanceof SpotLight) {
|
|
116
|
+
const color = Array.isArray(node.color) ? [...node.color] : [node.color.x, node.color.y, node.color.z];
|
|
117
|
+
return {
|
|
118
|
+
color,
|
|
119
|
+
intensity: node.intensity,
|
|
120
|
+
castsShadow: node.castsShadow,
|
|
121
|
+
...(node instanceof PointLight || node instanceof SpotLight ? { range: node.range } : {}),
|
|
122
|
+
...(node instanceof SpotLight ? { angle: node.angle, penumbra: node.penumbra } : {})
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=SceneSerializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SceneSerializer.js","sourceRoot":"","sources":["../../../../packages/scene/src/SceneSerializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Light } from "./Light.js";
|
|
2
|
+
export declare class SpotLight extends Light {
|
|
3
|
+
private currentAngle;
|
|
4
|
+
private currentPenumbra;
|
|
5
|
+
private currentRange;
|
|
6
|
+
constructor(name?: string, id?: string);
|
|
7
|
+
get angle(): number;
|
|
8
|
+
set angle(value: number);
|
|
9
|
+
get penumbra(): number;
|
|
10
|
+
set penumbra(value: number);
|
|
11
|
+
get range(): number;
|
|
12
|
+
set range(value: number);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=SpotLight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpotLight.d.ts","sourceRoot":"","sources":["../../../../packages/scene/src/SpotLight.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,qBAAa,SAAU,SAAQ,KAAK;IAClC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,YAAY,CAAM;gBAEd,IAAI,SAAc,EAAE,EAAE,CAAC,EAAE,MAAM;IAI3C,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAGtB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,MAAM,EAGzB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAGtB;CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ValidationError } from "@aura3d/core";
|
|
2
|
+
import { Light } from "./Light.js";
|
|
3
|
+
export class SpotLight extends Light {
|
|
4
|
+
currentAngle = Math.PI / 4;
|
|
5
|
+
currentPenumbra = 0;
|
|
6
|
+
currentRange = 10;
|
|
7
|
+
constructor(name = "SpotLight", id) {
|
|
8
|
+
super("spot", name, id);
|
|
9
|
+
}
|
|
10
|
+
get angle() {
|
|
11
|
+
return this.currentAngle;
|
|
12
|
+
}
|
|
13
|
+
set angle(value) {
|
|
14
|
+
if (!(value > 0 && value < Math.PI / 2))
|
|
15
|
+
throw new ValidationError("SPOT_LIGHT_ANGLE", "Spot light angle must be within (0, PI / 2).");
|
|
16
|
+
this.currentAngle = value;
|
|
17
|
+
}
|
|
18
|
+
get penumbra() {
|
|
19
|
+
return this.currentPenumbra;
|
|
20
|
+
}
|
|
21
|
+
set penumbra(value) {
|
|
22
|
+
if (!(value >= 0 && value <= 1))
|
|
23
|
+
throw new ValidationError("SPOT_LIGHT_PENUMBRA", "Spot light penumbra must be within [0, 1].");
|
|
24
|
+
this.currentPenumbra = value;
|
|
25
|
+
}
|
|
26
|
+
get range() {
|
|
27
|
+
return this.currentRange;
|
|
28
|
+
}
|
|
29
|
+
set range(value) {
|
|
30
|
+
if (!(value > 0) || !Number.isFinite(value))
|
|
31
|
+
throw new ValidationError("SPOT_LIGHT_RANGE", "Spot light range must be positive.");
|
|
32
|
+
this.currentRange = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=SpotLight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpotLight.js","sourceRoot":"","sources":["../../../../packages/scene/src/SpotLight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,OAAO,SAAU,SAAQ,KAAK;IAC1B,YAAY,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3B,eAAe,GAAG,CAAC,CAAC;IACpB,YAAY,GAAG,EAAE,CAAC;IAE1B,YAAY,IAAI,GAAG,WAAW,EAAE,EAAW;QACzC,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,IAAI,KAAK,CAAC,KAAa;QACrB,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;YAAE,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,8CAA8C,CAAC,CAAC;QACvI,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC5B,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,IAAI,QAAQ,CAAC,KAAa;QACxB,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE,4CAA4C,CAAC,CAAC;QAChI,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IAC/B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,IAAI,KAAK,CAAC,KAAa;QACrB,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,oCAAoC,CAAC,CAAC;QACjI,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Mat4, type Quat, type Vec3 } from "./MathTypes.js";
|
|
2
|
+
export declare class TransformNode {
|
|
3
|
+
private dirty;
|
|
4
|
+
private readonly dirtyListeners;
|
|
5
|
+
matrixAutoUpdate: boolean;
|
|
6
|
+
readonly position: Vec3;
|
|
7
|
+
readonly rotation: Quat;
|
|
8
|
+
readonly scale: Vec3;
|
|
9
|
+
localMatrix: Mat4;
|
|
10
|
+
worldMatrix: Mat4;
|
|
11
|
+
inverseWorldMatrix: Mat4;
|
|
12
|
+
setPosition(x: number, y: number, z: number): this;
|
|
13
|
+
setRotation(x: number, y: number, z: number, w: number): this;
|
|
14
|
+
setScale(x: number, y: number, z: number): this;
|
|
15
|
+
setFromLocalMatrix(matrix: Mat4): this;
|
|
16
|
+
setLocalMatrix(matrix: Mat4, options?: {
|
|
17
|
+
readonly decompose?: boolean;
|
|
18
|
+
readonly matrixAutoUpdate?: boolean;
|
|
19
|
+
}): this;
|
|
20
|
+
setMatrixAutoUpdate(enabled: boolean): this;
|
|
21
|
+
markDirty(): this;
|
|
22
|
+
onDirty(listener: () => void): () => void;
|
|
23
|
+
isDirty(): boolean;
|
|
24
|
+
updateWorld(parentWorld?: Mat4, force?: boolean): boolean;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=TransformNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransformNode.d.ts","sourceRoot":"","sources":["../../../../packages/scene/src/TransformNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,IAAI,EACV,MAAM,gBAAgB,CAAC;AAExB,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IACxD,gBAAgB,UAAQ;IACxB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAa;IACpC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAgB;IACvC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAa;IACjC,WAAW,EAAE,IAAI,CAAkB;IACnC,WAAW,EAAE,IAAI,CAAkB;IACnC,kBAAkB,EAAE,IAAI,CAAkB;IAE1C,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAOlD,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAS7D,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAO/C,kBAAkB,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI;IAetC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,GAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,IAAI;IAoBvH,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAK3C,SAAS,IAAI,IAAI;IAQjB,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAKzC,OAAO,IAAI,OAAO;IAIlB,WAAW,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,KAAK,UAAQ,GAAG,OAAO;CAWxD"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { cloneMat4, composeMat4, decomposeMat4, identityMat4, invertMat4, multiplyMat4, normalizeQuat } from "./MathTypes.js";
|
|
2
|
+
export class TransformNode {
|
|
3
|
+
dirty = true;
|
|
4
|
+
dirtyListeners = new Set();
|
|
5
|
+
matrixAutoUpdate = true;
|
|
6
|
+
position = [0, 0, 0];
|
|
7
|
+
rotation = [0, 0, 0, 1];
|
|
8
|
+
scale = [1, 1, 1];
|
|
9
|
+
localMatrix = identityMat4();
|
|
10
|
+
worldMatrix = identityMat4();
|
|
11
|
+
inverseWorldMatrix = identityMat4();
|
|
12
|
+
setPosition(x, y, z) {
|
|
13
|
+
this.position[0] = x;
|
|
14
|
+
this.position[1] = y;
|
|
15
|
+
this.position[2] = z;
|
|
16
|
+
return this.markDirty();
|
|
17
|
+
}
|
|
18
|
+
setRotation(x, y, z, w) {
|
|
19
|
+
const normalized = normalizeQuat([x, y, z, w]);
|
|
20
|
+
this.rotation[0] = normalized[0];
|
|
21
|
+
this.rotation[1] = normalized[1];
|
|
22
|
+
this.rotation[2] = normalized[2];
|
|
23
|
+
this.rotation[3] = normalized[3];
|
|
24
|
+
return this.markDirty();
|
|
25
|
+
}
|
|
26
|
+
setScale(x, y, z) {
|
|
27
|
+
this.scale[0] = x;
|
|
28
|
+
this.scale[1] = y;
|
|
29
|
+
this.scale[2] = z;
|
|
30
|
+
return this.markDirty();
|
|
31
|
+
}
|
|
32
|
+
setFromLocalMatrix(matrix) {
|
|
33
|
+
const decomposed = decomposeMat4(matrix);
|
|
34
|
+
this.position[0] = decomposed.position[0];
|
|
35
|
+
this.position[1] = decomposed.position[1];
|
|
36
|
+
this.position[2] = decomposed.position[2];
|
|
37
|
+
this.rotation[0] = decomposed.rotation[0];
|
|
38
|
+
this.rotation[1] = decomposed.rotation[1];
|
|
39
|
+
this.rotation[2] = decomposed.rotation[2];
|
|
40
|
+
this.rotation[3] = decomposed.rotation[3];
|
|
41
|
+
this.scale[0] = decomposed.scale[0];
|
|
42
|
+
this.scale[1] = decomposed.scale[1];
|
|
43
|
+
this.scale[2] = decomposed.scale[2];
|
|
44
|
+
return this.markDirty();
|
|
45
|
+
}
|
|
46
|
+
setLocalMatrix(matrix, options = {}) {
|
|
47
|
+
if (!matrix.every(Number.isFinite))
|
|
48
|
+
throw new Error("Transform local matrix must contain finite values.");
|
|
49
|
+
this.localMatrix = cloneMat4(matrix);
|
|
50
|
+
this.matrixAutoUpdate = options.matrixAutoUpdate ?? false;
|
|
51
|
+
if (options.decompose ?? true) {
|
|
52
|
+
const decomposed = decomposeMat4(matrix);
|
|
53
|
+
this.position[0] = decomposed.position[0];
|
|
54
|
+
this.position[1] = decomposed.position[1];
|
|
55
|
+
this.position[2] = decomposed.position[2];
|
|
56
|
+
this.rotation[0] = decomposed.rotation[0];
|
|
57
|
+
this.rotation[1] = decomposed.rotation[1];
|
|
58
|
+
this.rotation[2] = decomposed.rotation[2];
|
|
59
|
+
this.rotation[3] = decomposed.rotation[3];
|
|
60
|
+
this.scale[0] = decomposed.scale[0];
|
|
61
|
+
this.scale[1] = decomposed.scale[1];
|
|
62
|
+
this.scale[2] = decomposed.scale[2];
|
|
63
|
+
}
|
|
64
|
+
return this.markDirty();
|
|
65
|
+
}
|
|
66
|
+
setMatrixAutoUpdate(enabled) {
|
|
67
|
+
this.matrixAutoUpdate = enabled;
|
|
68
|
+
return this.markDirty();
|
|
69
|
+
}
|
|
70
|
+
markDirty() {
|
|
71
|
+
if (!this.dirty) {
|
|
72
|
+
this.dirty = true;
|
|
73
|
+
for (const listener of [...this.dirtyListeners])
|
|
74
|
+
listener();
|
|
75
|
+
}
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
onDirty(listener) {
|
|
79
|
+
this.dirtyListeners.add(listener);
|
|
80
|
+
return () => this.dirtyListeners.delete(listener);
|
|
81
|
+
}
|
|
82
|
+
isDirty() {
|
|
83
|
+
return this.dirty;
|
|
84
|
+
}
|
|
85
|
+
updateWorld(parentWorld, force = false) {
|
|
86
|
+
const shouldUpdate = force || this.dirty;
|
|
87
|
+
if (!shouldUpdate)
|
|
88
|
+
return false;
|
|
89
|
+
if (this.matrixAutoUpdate) {
|
|
90
|
+
this.localMatrix = composeMat4(this.position, this.rotation, this.scale);
|
|
91
|
+
}
|
|
92
|
+
this.worldMatrix = parentWorld ? multiplyMat4(parentWorld, this.localMatrix) : cloneMat4(this.localMatrix);
|
|
93
|
+
this.inverseWorldMatrix = invertMat4(this.worldMatrix);
|
|
94
|
+
this.dirty = false;
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=TransformNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransformNode.js","sourceRoot":"","sources":["../../../../packages/scene/src/TransformNode.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export * from "./MathTypes.js";
|
|
2
|
+
export * from "./TransformNode.js";
|
|
3
|
+
export * from "./Bounds.js";
|
|
4
|
+
export * from "./SceneNode.js";
|
|
5
|
+
export * from "./Object3D.js";
|
|
6
|
+
export * from "./Hierarchy.js";
|
|
7
|
+
export * from "./Camera.js";
|
|
8
|
+
export * from "./PerspectiveCamera.js";
|
|
9
|
+
export * from "./OrthographicCamera.js";
|
|
10
|
+
export * from "./Light.js";
|
|
11
|
+
export * from "./DirectionalLight.js";
|
|
12
|
+
export * from "./PointLight.js";
|
|
13
|
+
export * from "./SpotLight.js";
|
|
14
|
+
export * from "./Layers.js";
|
|
15
|
+
export * from "./Lights.js";
|
|
16
|
+
export * from "./Renderable.js";
|
|
17
|
+
export * from "./SceneQuery.js";
|
|
18
|
+
export * from "./SceneMetadata.js";
|
|
19
|
+
export * from "./Scene.js";
|
|
20
|
+
export * from "./SceneSerializer.js";
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/scene/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export * from "./MathTypes.js";
|
|
2
|
+
export * from "./TransformNode.js";
|
|
3
|
+
export * from "./Bounds.js";
|
|
4
|
+
export * from "./SceneNode.js";
|
|
5
|
+
export * from "./Object3D.js";
|
|
6
|
+
export * from "./Hierarchy.js";
|
|
7
|
+
export * from "./Camera.js";
|
|
8
|
+
export * from "./PerspectiveCamera.js";
|
|
9
|
+
export * from "./OrthographicCamera.js";
|
|
10
|
+
export * from "./Light.js";
|
|
11
|
+
export * from "./DirectionalLight.js";
|
|
12
|
+
export * from "./PointLight.js";
|
|
13
|
+
export * from "./SpotLight.js";
|
|
14
|
+
export * from "./Layers.js";
|
|
15
|
+
export * from "./Lights.js";
|
|
16
|
+
export * from "./Renderable.js";
|
|
17
|
+
export * from "./SceneQuery.js";
|
|
18
|
+
export * from "./SceneMetadata.js";
|
|
19
|
+
export * from "./Scene.js";
|
|
20
|
+
export * from "./SceneSerializer.js";
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/scene/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aura3d/scene",
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@aura3d/core": "1.0.6",
|
|
16
|
+
"@aura3d/math": "1.0.6"
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/Bounds.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Box3, Vector3 } from "@aura3d/math";
|
|
2
|
+
import { transformPoint, type Mat4, type Vec3 } from "./MathTypes.js";
|
|
3
|
+
|
|
4
|
+
export class Bounds3 {
|
|
5
|
+
min: Vec3;
|
|
6
|
+
max: Vec3;
|
|
7
|
+
|
|
8
|
+
constructor(min: Vec3 = [Infinity, Infinity, Infinity], max: Vec3 = [-Infinity, -Infinity, -Infinity]) {
|
|
9
|
+
this.min = [...min] as Vec3;
|
|
10
|
+
this.max = [...max] as Vec3;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static fromCenterSize(center: Vec3, size: Vec3): Bounds3 {
|
|
14
|
+
return new Bounds3(
|
|
15
|
+
[center[0] - size[0] / 2, center[1] - size[1] / 2, center[2] - size[2] / 2],
|
|
16
|
+
[center[0] + size[0] / 2, center[1] + size[1] / 2, center[2] + size[2] / 2]
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static fromMathBox(box: Box3): Bounds3 {
|
|
21
|
+
return new Bounds3(box.min.toArray(), box.max.toArray());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
isEmpty(): boolean {
|
|
25
|
+
return this.toMathBox().isEmpty();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
union(other: Bounds3): Bounds3 {
|
|
29
|
+
return Bounds3.fromMathBox(this.toMathBox().union(other.toMathBox()));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
intersects(other: Bounds3): boolean {
|
|
33
|
+
return this.toMathBox().intersectsBox(other.toMathBox());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
containsPoint(point: Vec3): boolean {
|
|
37
|
+
return this.toMathBox().containsPoint(new Vector3(point[0], point[1], point[2]));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
transform(matrix: Mat4): Bounds3 {
|
|
41
|
+
if (this.isEmpty()) return new Bounds3();
|
|
42
|
+
const corners: Vec3[] = [
|
|
43
|
+
[this.min[0], this.min[1], this.min[2]],
|
|
44
|
+
[this.max[0], this.min[1], this.min[2]],
|
|
45
|
+
[this.min[0], this.max[1], this.min[2]],
|
|
46
|
+
[this.min[0], this.min[1], this.max[2]],
|
|
47
|
+
[this.max[0], this.max[1], this.min[2]],
|
|
48
|
+
[this.max[0], this.min[1], this.max[2]],
|
|
49
|
+
[this.min[0], this.max[1], this.max[2]],
|
|
50
|
+
[this.max[0], this.max[1], this.max[2]]
|
|
51
|
+
];
|
|
52
|
+
return corners.reduce((bounds, corner) => bounds.includePoint(transformPoint(matrix, corner)), new Bounds3());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
includePoint(point: Vec3): Bounds3 {
|
|
56
|
+
this.min = [Math.min(this.min[0], point[0]), Math.min(this.min[1], point[1]), Math.min(this.min[2], point[2])];
|
|
57
|
+
this.max = [Math.max(this.max[0], point[0]), Math.max(this.max[1], point[1]), Math.max(this.max[2], point[2])];
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
clone(): Bounds3 {
|
|
62
|
+
return new Bounds3(this.min, this.max);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
toMathBox(): Box3 {
|
|
66
|
+
return new Box3(new Vector3(this.min[0], this.min[1], this.min[2]), new Vector3(this.max[0], this.max[1], this.max[2]));
|
|
67
|
+
}
|
|
68
|
+
}
|
package/src/Camera.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ValidationError } from "@aura3d/core";
|
|
2
|
+
import { Frustum } from "@aura3d/math";
|
|
3
|
+
import { extractFrustumPlanes, identityMat4, multiplyMat4, toMathMat4, type Mat4, type PlaneTuple } from "./MathTypes.js";
|
|
4
|
+
import { SceneNode } from "./SceneNode.js";
|
|
5
|
+
|
|
6
|
+
export interface CameraViewport {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export abstract class Camera extends SceneNode {
|
|
14
|
+
viewport: CameraViewport = { x: 0, y: 0, width: 1, height: 1 };
|
|
15
|
+
readonly frustumPlanes: PlaneTuple[] = [];
|
|
16
|
+
frustum: Frustum = Frustum.fromMatrix(toMathMat4(identityMat4()));
|
|
17
|
+
projectionMatrix: Mat4;
|
|
18
|
+
viewMatrix: Mat4;
|
|
19
|
+
viewProjectionMatrix: Mat4;
|
|
20
|
+
|
|
21
|
+
protected constructor(name: string, id?: string) {
|
|
22
|
+
super({ id, name });
|
|
23
|
+
this.projectionMatrix = identityMat4();
|
|
24
|
+
this.viewMatrix = this.transform.inverseWorldMatrix;
|
|
25
|
+
this.viewProjectionMatrix = multiplyMat4(this.projectionMatrix, this.viewMatrix);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
abstract computeProjectionMatrix(): Mat4;
|
|
29
|
+
|
|
30
|
+
updateCameraMatrices(): void {
|
|
31
|
+
updateAncestors(this);
|
|
32
|
+
this.updateWorldTransform();
|
|
33
|
+
this.projectionMatrix = this.computeProjectionMatrix();
|
|
34
|
+
this.viewMatrix = this.transform.inverseWorldMatrix;
|
|
35
|
+
this.viewProjectionMatrix = multiplyMat4(this.projectionMatrix, this.viewMatrix);
|
|
36
|
+
this.frustum = Frustum.fromMatrix(toMathMat4(this.viewProjectionMatrix));
|
|
37
|
+
this.frustumPlanes.splice(0, this.frustumPlanes.length, ...extractFrustumPlanes(this.viewProjectionMatrix));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
setViewport(viewport: CameraViewport): void {
|
|
41
|
+
if (viewport.width <= 0 || viewport.height <= 0) throw new ValidationError("CAMERA_VIEWPORT", "Camera viewport dimensions must be positive.");
|
|
42
|
+
this.viewport = { ...viewport };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function updateAncestors(node: SceneNode): void {
|
|
47
|
+
const ancestors: SceneNode[] = [];
|
|
48
|
+
let parent = node.parent;
|
|
49
|
+
while (parent) {
|
|
50
|
+
ancestors.unshift(parent);
|
|
51
|
+
parent = parent.parent;
|
|
52
|
+
}
|
|
53
|
+
for (const ancestor of ancestors) {
|
|
54
|
+
ancestor.transform.updateWorld(ancestor.parent?.transform.worldMatrix);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { normalizeVec3, type Vec3 } from "./MathTypes.js";
|
|
2
|
+
import { Light } from "./Light.js";
|
|
3
|
+
|
|
4
|
+
export class DirectionalLight extends Light {
|
|
5
|
+
constructor(name = "DirectionalLight", id?: string) {
|
|
6
|
+
super("directional", name, id);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
getDirection(): Vec3 {
|
|
10
|
+
const m = this.transform.worldMatrix;
|
|
11
|
+
return normalizeVec3([-m[8], -m[9], -m[10]]);
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/Hierarchy.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { assertCanParent, type AddChildOptions, type SceneNode } from "./SceneNode.js";
|
|
2
|
+
|
|
3
|
+
export function isAncestor(ancestor: SceneNode, node: SceneNode): boolean {
|
|
4
|
+
return ancestor.isAncestorOf(node);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function reparent(node: SceneNode, newParent: SceneNode, options: AddChildOptions = {}): void {
|
|
8
|
+
assertCanParent(newParent, node);
|
|
9
|
+
newParent.addChild(node, options);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function batchReparent(nodes: readonly SceneNode[], newParent: SceneNode, options: AddChildOptions = {}): void {
|
|
13
|
+
for (const node of nodes) reparent(node, newParent, options);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function removeAllChildren(node: SceneNode): SceneNode[] {
|
|
17
|
+
const removed = [...node.children];
|
|
18
|
+
for (const child of removed) node.removeChild(child);
|
|
19
|
+
return removed;
|
|
20
|
+
}
|
package/src/Layers.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export class Layers {
|
|
2
|
+
mask = 1;
|
|
3
|
+
|
|
4
|
+
set(channel: number): void {
|
|
5
|
+
this.mask = 1 << validateChannel(channel);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
enable(channel: number): void {
|
|
9
|
+
this.mask |= 1 << validateChannel(channel);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
disable(channel: number): void {
|
|
13
|
+
this.mask &= ~(1 << validateChannel(channel));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
test(other: Layers): boolean {
|
|
17
|
+
return (this.mask & other.mask) !== 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function validateChannel(channel: number): number {
|
|
22
|
+
if (!Number.isInteger(channel) || channel < 0 || channel > 31) throw new Error("Layer channel must be an integer in [0, 31].");
|
|
23
|
+
return channel;
|
|
24
|
+
}
|
package/src/Light.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ValidationError } from "@aura3d/core";
|
|
2
|
+
import { type Vector3 } from "@aura3d/math";
|
|
3
|
+
import { type Vec3 } from "./MathTypes.js";
|
|
4
|
+
import { SceneNode } from "./SceneNode.js";
|
|
5
|
+
|
|
6
|
+
export type LightKind = "directional" | "point" | "spot";
|
|
7
|
+
|
|
8
|
+
export abstract class Light extends SceneNode {
|
|
9
|
+
readonly kind: LightKind;
|
|
10
|
+
color: Vec3 | Vector3 = [1, 1, 1];
|
|
11
|
+
castsShadow = false;
|
|
12
|
+
private currentIntensity = 1;
|
|
13
|
+
|
|
14
|
+
protected constructor(kind: LightKind, name: string, id?: string) {
|
|
15
|
+
super({ id, name });
|
|
16
|
+
this.kind = kind;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get intensity(): number {
|
|
20
|
+
return this.currentIntensity;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
set intensity(value: number) {
|
|
24
|
+
if (!(value >= 0) || !Number.isFinite(value)) throw new ValidationError("LIGHT_INTENSITY", "Light intensity must be a finite non-negative number.");
|
|
25
|
+
this.currentIntensity = value;
|
|
26
|
+
}
|
|
27
|
+
}
|