@needle-tools/engine 4.11.3 → 4.11.4-next.a568de7
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/CHANGELOG.md +4 -0
- package/dist/generateMeshBVH.worker-B9bjdr6J.js +25 -0
- package/dist/{needle-engine.bundle-B_aGaFmh.js → needle-engine.bundle-DpWrB4yf.js} +5306 -5268
- package/dist/{needle-engine.bundle-TscA1IdQ.min.js → needle-engine.bundle-lEVjhicZ.min.js} +133 -133
- package/dist/{needle-engine.bundle-YQ3I1QD8.umd.cjs → needle-engine.bundle-nX51yB5a.umd.cjs} +132 -132
- package/dist/needle-engine.js +2 -2
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{vendor-H-9KkM5B.umd.cjs → vendor-6kAXU6fm.umd.cjs} +39 -39
- package/dist/{vendor-BahM12Xj.min.js → vendor-CsyK1CFs.min.js} +46 -46
- package/dist/{vendor-Becub4o1.js → vendor-petGQl0N.js} +3130 -3069
- package/lib/engine/api.d.ts +1 -0
- package/lib/engine/api.js +1 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/engine_addressables.d.ts +74 -11
- package/lib/engine/engine_addressables.js +74 -11
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_camera.fit.d.ts +48 -3
- package/lib/engine/engine_camera.fit.js +29 -0
- package/lib/engine/engine_camera.fit.js.map +1 -1
- package/lib/engine/engine_context.d.ts +18 -3
- package/lib/engine/engine_context.js +18 -3
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +0 -23
- package/lib/engine/engine_utils.js +0 -202
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/engine_utils_attributes.d.ts +48 -0
- package/lib/engine/engine_utils_attributes.js +70 -0
- package/lib/engine/engine_utils_attributes.js.map +1 -0
- package/lib/engine/engine_utils_qrcode.d.ts +23 -0
- package/lib/engine/engine_utils_qrcode.js +234 -0
- package/lib/engine/engine_utils_qrcode.js.map +1 -0
- package/lib/engine/extensions/NEEDLE_components.d.ts +4 -4
- package/lib/engine/extensions/NEEDLE_components.js +36 -17
- package/lib/engine/extensions/NEEDLE_components.js.map +1 -1
- package/lib/engine/webcomponents/buttons.js +1 -1
- package/lib/engine/webcomponents/buttons.js.map +1 -1
- package/lib/engine-components/Animation.d.ts +1 -1
- package/lib/engine-components/Animation.js +1 -1
- package/lib/engine-components/AnimationCurve.d.ts +3 -0
- package/lib/engine-components/AnimationCurve.js +3 -0
- package/lib/engine-components/AnimationCurve.js.map +1 -1
- package/lib/engine-components/Animator.d.ts +2 -1
- package/lib/engine-components/Animator.js +2 -1
- package/lib/engine-components/Animator.js.map +1 -1
- package/lib/engine-components/AnimatorController.d.ts +3 -0
- package/lib/engine-components/AnimatorController.js +3 -0
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/LookAtConstraint.d.ts +4 -0
- package/lib/engine-components/LookAtConstraint.js +4 -0
- package/lib/engine-components/LookAtConstraint.js.map +1 -1
- package/lib/engine-components/NeedleMenu.d.ts +1 -0
- package/lib/engine-components/NeedleMenu.js +1 -0
- package/lib/engine-components/NeedleMenu.js.map +1 -1
- package/lib/engine-components/NestedGltf.d.ts +3 -0
- package/lib/engine-components/NestedGltf.js +3 -0
- package/lib/engine-components/NestedGltf.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.d.ts +4 -0
- package/lib/engine-components/ReflectionProbe.js +4 -0
- package/lib/engine-components/ReflectionProbe.js.map +1 -1
- package/lib/engine-components/Renderer.js +14 -40
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/RendererLightmap.d.ts +7 -0
- package/lib/engine-components/RendererLightmap.js +30 -21
- package/lib/engine-components/RendererLightmap.js.map +1 -1
- package/lib/engine-components/SeeThrough.d.ts +3 -0
- package/lib/engine-components/SeeThrough.js +3 -0
- package/lib/engine-components/SeeThrough.js.map +1 -1
- package/lib/engine-components/Skybox.d.ts +3 -0
- package/lib/engine-components/Skybox.js +3 -0
- package/lib/engine-components/Skybox.js.map +1 -1
- package/lib/engine-components/SpriteRenderer.d.ts +14 -1
- package/lib/engine-components/SpriteRenderer.js +17 -1
- package/lib/engine-components/SpriteRenderer.js.map +1 -1
- package/lib/engine-components/splines/Spline.d.ts +3 -0
- package/lib/engine-components/splines/Spline.js +3 -0
- package/lib/engine-components/splines/Spline.js.map +1 -1
- package/lib/engine-components/splines/SplineUtils.d.ts +3 -0
- package/lib/engine-components/splines/SplineUtils.js +3 -0
- package/lib/engine-components/splines/SplineUtils.js.map +1 -1
- package/lib/engine-components/splines/SplineWalker.d.ts +3 -0
- package/lib/engine-components/splines/SplineWalker.js +3 -0
- package/lib/engine-components/splines/SplineWalker.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +2 -1
- package/lib/engine-components/timeline/PlayableDirector.js +16 -9
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/SignalAsset.d.ts +11 -1
- package/lib/engine-components/timeline/SignalAsset.js +11 -1
- package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
- package/lib/engine-components/ui/Raycaster.d.ts +18 -0
- package/lib/engine-components/ui/Raycaster.js +18 -0
- package/lib/engine-components/ui/Raycaster.js.map +1 -1
- package/package.json +2 -2
- package/src/engine/api.ts +1 -0
- package/src/engine/engine_addressables.ts +76 -11
- package/src/engine/engine_camera.fit.ts +50 -4
- package/src/engine/engine_context.ts +18 -3
- package/src/engine/engine_utils.ts +0 -229
- package/src/engine/engine_utils_attributes.ts +72 -0
- package/src/engine/engine_utils_qrcode.ts +266 -0
- package/src/engine/extensions/NEEDLE_components.ts +47 -26
- package/src/engine/webcomponents/buttons.ts +1 -1
- package/src/engine-components/Animation.ts +1 -1
- package/src/engine-components/AnimationCurve.ts +4 -1
- package/src/engine-components/Animator.ts +3 -2
- package/src/engine-components/AnimatorController.ts +3 -0
- package/src/engine-components/LookAtConstraint.ts +6 -1
- package/src/engine-components/NeedleMenu.ts +1 -0
- package/src/engine-components/NestedGltf.ts +3 -0
- package/src/engine-components/ReflectionProbe.ts +4 -0
- package/src/engine-components/Renderer.ts +14 -42
- package/src/engine-components/RendererLightmap.ts +34 -20
- package/src/engine-components/SeeThrough.ts +3 -0
- package/src/engine-components/Skybox.ts +3 -0
- package/src/engine-components/SpriteRenderer.ts +18 -2
- package/src/engine-components/splines/Spline.ts +3 -0
- package/src/engine-components/splines/SplineUtils.ts +3 -1
- package/src/engine-components/splines/SplineWalker.ts +3 -0
- package/src/engine-components/timeline/PlayableDirector.ts +16 -10
- package/src/engine-components/timeline/SignalAsset.ts +13 -2
- package/src/engine-components/ui/Raycaster.ts +19 -0
- package/dist/generateMeshBVH.worker-2qGLkQjg.js +0 -25
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Object3D } from "three";
|
|
2
2
|
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';
|
|
3
3
|
import { type GLTF, type GLTFLoaderPlugin, GLTFParser } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
4
|
+
import { isDevEnvironment } from "../debug/debug.js";
|
|
4
5
|
|
|
5
6
|
import { builtinComponentKeyName } from "../engine_constants.js";
|
|
6
7
|
import { debugExtension } from "../engine_default_parameters.js";
|
|
7
8
|
import { getLoader } from "../engine_gltf.js";
|
|
8
9
|
import { type NodeToObjectMap, type ObjectToNodeMap, SerializationContext } from "../engine_serialization_core.js";
|
|
9
10
|
import { apply } from "../js-extensions/index.js";
|
|
10
|
-
import { maskGltfAssociation,resolveReferences } from "./extension_utils.js";
|
|
11
|
+
import { maskGltfAssociation, resolveReferences } from "./extension_utils.js";
|
|
11
12
|
|
|
12
13
|
export const debug = debugExtension
|
|
13
14
|
const componentsArrayExportKey = "$___Export_Components";
|
|
@@ -15,7 +16,7 @@ const componentsArrayExportKey = "$___Export_Components";
|
|
|
15
16
|
export const EXTENSION_NAME = "NEEDLE_components";
|
|
16
17
|
|
|
17
18
|
class ExtensionData {
|
|
18
|
-
[builtinComponentKeyName]?: Array<
|
|
19
|
+
[builtinComponentKeyName]?: Array<Record<string, any> | null>
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
class ExportData {
|
|
@@ -35,14 +36,7 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
|
|
|
35
36
|
get name(): string {
|
|
36
37
|
return EXTENSION_NAME;
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
-
// import
|
|
40
|
-
parser?: GLTFParser;
|
|
41
|
-
nodeToObjectMap: NodeToObjectMap = {};
|
|
42
|
-
/** The loaded gltf */
|
|
43
|
-
gltf: GLTF | null = null;
|
|
44
|
-
|
|
45
|
-
// export
|
|
39
|
+
// #region export
|
|
46
40
|
exportContext!: { [nodeIndex: number]: ExportData };
|
|
47
41
|
objectToNodeMap: ObjectToNodeMap = {};
|
|
48
42
|
context!: SerializationContext;
|
|
@@ -112,7 +106,7 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
|
|
|
112
106
|
|
|
113
107
|
writeNode(node: Object3D, nodeDef) {
|
|
114
108
|
const nodeIndex = this.writer.json.nodes.length;
|
|
115
|
-
if (debug)
|
|
109
|
+
if (debug)
|
|
116
110
|
console.log(node.name, nodeIndex, node.uuid);
|
|
117
111
|
const context = new ExportData(node, nodeIndex, nodeDef);
|
|
118
112
|
this.exportContext[nodeIndex] = context;
|
|
@@ -158,8 +152,13 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
|
|
|
158
152
|
|
|
159
153
|
|
|
160
154
|
// -------------------------------------
|
|
161
|
-
//
|
|
162
|
-
|
|
155
|
+
// #region import
|
|
156
|
+
parser?: GLTFParser;
|
|
157
|
+
nodeToObjectMap: NodeToObjectMap = {};
|
|
158
|
+
/** The loaded gltf */
|
|
159
|
+
gltf: GLTF | null = null;
|
|
160
|
+
|
|
161
|
+
|
|
163
162
|
beforeRoot() {
|
|
164
163
|
if (debug)
|
|
165
164
|
console.log("BEGIN LOAD");
|
|
@@ -167,7 +166,6 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
|
|
|
167
166
|
return null;
|
|
168
167
|
}
|
|
169
168
|
|
|
170
|
-
// called by GLTFLoader
|
|
171
169
|
async afterRoot(result: GLTF): Promise<void> {
|
|
172
170
|
this.gltf = result;
|
|
173
171
|
|
|
@@ -175,8 +173,7 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
|
|
|
175
173
|
const ext = parser?.extensions;
|
|
176
174
|
if (!ext) return;
|
|
177
175
|
const hasExtension = ext[this.name];
|
|
178
|
-
if (debug)
|
|
179
|
-
console.log("After root", result, this.parser, ext);
|
|
176
|
+
if (debug) console.log("After root", result, this.parser, ext);
|
|
180
177
|
|
|
181
178
|
const loadComponents: Array<Promise<void>> = [];
|
|
182
179
|
if (hasExtension === true) {
|
|
@@ -204,7 +201,7 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
|
|
|
204
201
|
|
|
205
202
|
apply(obj);
|
|
206
203
|
|
|
207
|
-
loadComponents.push(this.createComponents(obj, data));
|
|
204
|
+
loadComponents.push(this.createComponents(result, node, obj, data));
|
|
208
205
|
}
|
|
209
206
|
}
|
|
210
207
|
}
|
|
@@ -220,7 +217,7 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
|
|
|
220
217
|
}
|
|
221
218
|
}
|
|
222
219
|
|
|
223
|
-
private async createComponents(obj: Object3D, data: ExtensionData) {
|
|
220
|
+
private async createComponents(result: GLTF, node: Node, obj: Object3D, data: ExtensionData) {
|
|
224
221
|
if (!data) return;
|
|
225
222
|
const componentData = data[builtinComponentKeyName];
|
|
226
223
|
if (componentData) {
|
|
@@ -228,20 +225,42 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
|
|
|
228
225
|
if (debug)
|
|
229
226
|
console.log(obj.name, componentData);
|
|
230
227
|
for (const i in componentData) {
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
228
|
+
const data = componentData[i];
|
|
229
|
+
|
|
230
|
+
if (debug) console.log("Serialized data", JSON.parse(JSON.stringify(data)));
|
|
231
|
+
|
|
232
|
+
// Fix for https://linear.app/needle/issue/NE-6779/blender-export-has-missing-sharedmaterials
|
|
233
|
+
if (data?.name === "MeshRenderer" || data?.name === "SkinnedMeshRenderer") {
|
|
234
|
+
if (!data.sharedMaterials) {
|
|
235
|
+
let success = false;
|
|
236
|
+
if ("mesh" in node) {
|
|
237
|
+
const meshIndex = node.mesh;
|
|
238
|
+
if (typeof meshIndex === "number" && result.parser) {
|
|
239
|
+
const meshDef = result.parser.json.meshes?.[meshIndex];
|
|
240
|
+
if (meshDef?.primitives) {
|
|
241
|
+
data.sharedMaterials = meshDef.primitives.map(prim => {
|
|
242
|
+
return "/materials/" + (prim.material ?? 0);
|
|
243
|
+
});
|
|
244
|
+
success = true;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if(!success && (debug || isDevEnvironment())) {
|
|
249
|
+
console.warn(`[NEEDLE_components] Component '${data.name}' on object '${obj.name}' is not added to a mesh or failed to retrieve materials from glTF.`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
234
253
|
|
|
235
|
-
if (
|
|
254
|
+
if (data && this.parser) {
|
|
236
255
|
tasks.push(
|
|
237
|
-
resolveReferences(this.parser,
|
|
238
|
-
.catch(e => console.error(`Error while resolving references (see console for details)\n`, e, obj,
|
|
256
|
+
resolveReferences(this.parser, data)
|
|
257
|
+
.catch(e => console.error(`Error while resolving references (see console for details)\n`, e, obj, data))
|
|
239
258
|
);
|
|
240
259
|
}
|
|
241
260
|
|
|
242
261
|
obj.userData = obj.userData || {};
|
|
243
262
|
obj.userData[builtinComponentKeyName] = obj.userData[builtinComponentKeyName] || [];
|
|
244
|
-
obj.userData[builtinComponentKeyName].push(
|
|
263
|
+
obj.userData[builtinComponentKeyName].push(data);
|
|
245
264
|
}
|
|
246
265
|
await Promise.all(tasks).catch((e) => {
|
|
247
266
|
console.error("Error while loading components", e);
|
|
@@ -266,4 +285,6 @@ export class NEEDLE_components implements GLTFLoaderPlugin {
|
|
|
266
285
|
// // console.log(components);
|
|
267
286
|
// return null;
|
|
268
287
|
// }
|
|
269
|
-
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isDevEnvironment, showBalloonWarning } from "../debug/debug.js";
|
|
2
2
|
import { IContext } from "../engine_types.js";
|
|
3
|
-
import { generateQRCode
|
|
3
|
+
import { generateQRCode } from "../engine_utils_qrcode.js";
|
|
4
4
|
import { onXRSessionEnd, onXRSessionStart } from "../xr/events.js";
|
|
5
5
|
import { getIconElement } from "./icons.js";
|
|
6
6
|
|
|
@@ -58,7 +58,7 @@ declare type AnimationIdentifier = AnimationClip | number | string | undefined;
|
|
|
58
58
|
class Vec2 { x!: number; y!: number }
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
* Animation component to play animations on a GameObject
|
|
61
|
+
* Animation component to play animations on a GameObject.
|
|
62
62
|
* @category Animation and Sequencing
|
|
63
63
|
* @group Components
|
|
64
64
|
*/
|
|
@@ -27,7 +27,10 @@ export class Keyframe {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
* AnimationCurve is a representation of a curve that can be used to animate values over time.
|
|
30
|
+
* AnimationCurve is a representation of a curve that can be used to animate values over time.
|
|
31
|
+
*
|
|
32
|
+
* @category Animation
|
|
33
|
+
* @group Utilities
|
|
31
34
|
*/
|
|
32
35
|
export class AnimationCurve {
|
|
33
36
|
|
|
@@ -39,8 +39,9 @@ export declare class PlayOptions {
|
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
41
|
* The Animator component plays and manages animations on a GameObject.
|
|
42
|
-
* It works with an AnimatorController to handle state transitions and animation blending.
|
|
43
|
-
* A new AnimatorController can be created from code via `AnimatorController.createFromClips`.
|
|
42
|
+
* It works with an {@link AnimatorController} to handle state transitions and animation blending.
|
|
43
|
+
* A new AnimatorController can be created from code via `AnimatorController.createFromClips`.
|
|
44
|
+
*
|
|
44
45
|
* @category Animation and Sequencing
|
|
45
46
|
* @group Components
|
|
46
47
|
*/
|
|
@@ -51,6 +51,9 @@ declare type CreateAnimatorControllerOptions = {
|
|
|
51
51
|
*
|
|
52
52
|
* Use the static method {@link AnimatorController.createFromClips} to create
|
|
53
53
|
* an animator controller from a set of animation clips.
|
|
54
|
+
*
|
|
55
|
+
* @category Animation and Sequencing
|
|
56
|
+
* @group Utilities
|
|
54
57
|
*/
|
|
55
58
|
export class AnimatorController {
|
|
56
59
|
|
|
@@ -2,9 +2,14 @@ import { Object3D, Vector3 } from "three";
|
|
|
2
2
|
|
|
3
3
|
import { serializable } from "../engine/engine_serialization_decorator.js";
|
|
4
4
|
import { Behaviour } from "./Component.js";
|
|
5
|
+
import type { OrbitControls } from "./OrbitControls.js";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* A LookAtConstraint is used by OrbitControls to make the camera look at a target.
|
|
8
|
+
* A LookAtConstraint is used by OrbitControls to make the camera look at a target.
|
|
9
|
+
* This component is used by {@link OrbitControls} internally.
|
|
10
|
+
*
|
|
11
|
+
* @category Camera Controls
|
|
12
|
+
* @group Components
|
|
8
13
|
*/
|
|
9
14
|
export class LookAtConstraint extends Behaviour {
|
|
10
15
|
|
|
@@ -10,6 +10,9 @@ const debug = getParam("debugnestedgltf");
|
|
|
10
10
|
|
|
11
11
|
/** The nested gltf is a component that is used to load a gltf file when the component becomes active (start)
|
|
12
12
|
* It will load the gltf file and instantiate it as a child of the parent of the GameObject that has this component
|
|
13
|
+
*
|
|
14
|
+
* @category Asset Management
|
|
15
|
+
* @group Components
|
|
13
16
|
*/
|
|
14
17
|
export class NestedGltf extends Behaviour {
|
|
15
18
|
|
|
@@ -15,6 +15,10 @@ const $reflectionProbeKey = Symbol("reflectionProbeKey");
|
|
|
15
15
|
const $originalMaterial = Symbol("original material");
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
+
* A ReflectionProbe provides reflection data to materials within its defined area.
|
|
19
|
+
*
|
|
20
|
+
* - Sample: http://samples.needle.tools/reflection-probes
|
|
21
|
+
*
|
|
18
22
|
* @category Rendering
|
|
19
23
|
* @group Components
|
|
20
24
|
*/
|
|
@@ -69,7 +69,7 @@ class SharedMaterialArray implements ISharedMaterials {
|
|
|
69
69
|
set changed(value: boolean) {
|
|
70
70
|
if (value === true) {
|
|
71
71
|
if (debugRenderer)
|
|
72
|
-
console.warn("SharedMaterials have changed: " + this._renderer.name
|
|
72
|
+
console.warn("SharedMaterials have changed: " + this._renderer.name);
|
|
73
73
|
}
|
|
74
74
|
this._changed = value;
|
|
75
75
|
}
|
|
@@ -358,11 +358,15 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
358
358
|
//@ts-ignore
|
|
359
359
|
get sharedMaterials(): SharedMaterialArray {
|
|
360
360
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
361
|
+
if (this._originalMaterials === undefined) {
|
|
362
|
+
if (!this.__didAwake) {
|
|
363
|
+
// @ts-ignore (original materials will be set during deserialization)
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
this._originalMaterials = [];
|
|
368
|
+
}
|
|
369
|
+
}
|
|
366
370
|
|
|
367
371
|
if (!this._sharedMaterials || !this._sharedMaterials.is(this)) {
|
|
368
372
|
if (!this._originalMaterials) this._originalMaterials = [];
|
|
@@ -454,6 +458,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
454
458
|
this.context.addBeforeRenderListener(this.gameObject, this.onBeforeRenderThree);
|
|
455
459
|
}
|
|
456
460
|
|
|
461
|
+
this._lightmaps = undefined;
|
|
457
462
|
this.applyLightmapping();
|
|
458
463
|
|
|
459
464
|
if (showWireframe) {
|
|
@@ -468,8 +473,8 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
468
473
|
}
|
|
469
474
|
|
|
470
475
|
private applyLightmapping() {
|
|
471
|
-
if (this.lightmapIndex >= 0) {
|
|
472
|
-
const type = this.gameObject.type;
|
|
476
|
+
if (this.lightmapIndex >= 0 && !this._lightmaps) {
|
|
477
|
+
// const type = this.gameObject.type;
|
|
473
478
|
|
|
474
479
|
// use the override lightmap if its not undefined
|
|
475
480
|
const tex = this._lightmapTextureOverride !== undefined
|
|
@@ -477,45 +482,12 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
477
482
|
: this.context.lightmaps.tryGetLightmap(this.sourceId, this.lightmapIndex);
|
|
478
483
|
if (tex) {
|
|
479
484
|
if (!this._lightmaps) this._lightmaps = [];
|
|
480
|
-
|
|
481
|
-
|
|
482
485
|
const rm = new RendererLightmap(this);
|
|
483
486
|
rm.init(this.lightmapIndex, this.lightmapScaleOffset, tex);
|
|
484
487
|
this._lightmaps.push(rm);
|
|
485
|
-
|
|
486
|
-
// if (type === "Mesh") {
|
|
487
|
-
// const mat = this.gameObject["material"];
|
|
488
|
-
// if (!mat?.isMeshBasicMaterial) {
|
|
489
|
-
// if (this._lightmaps.length <= 0) {
|
|
490
|
-
// }
|
|
491
|
-
// const rm = this._lightmaps[0];
|
|
492
|
-
// rm.init(this.lightmapIndex, this.lightmapScaleOffset, tex);
|
|
493
|
-
// }
|
|
494
|
-
// else {
|
|
495
|
-
// if (mat)
|
|
496
|
-
// console.warn("Lightmapping is not supported on MeshBasicMaterial", mat.name)
|
|
497
|
-
// }
|
|
498
|
-
// }
|
|
499
|
-
// // for multi materials we need to loop through children
|
|
500
|
-
// // and then we add a lightmap renderer component to each of them
|
|
501
|
-
// else if (this.isMultiMaterialObject(this.gameObject) && this.sharedMaterials.length > 0) {
|
|
502
|
-
// for (let i = 0; i < this.gameObject.children.length; i++) {
|
|
503
|
-
// const child = this.gameObject.children[i];
|
|
504
|
-
// if (!child["material"]?.isMeshBasicMaterial) {
|
|
505
|
-
// let rm: RendererLightmap | undefined = undefined;
|
|
506
|
-
// if (i >= this._lightmaps.length) {
|
|
507
|
-
// rm = new RendererLightmap(child as Mesh, this.context);
|
|
508
|
-
// this._lightmaps.push(rm);
|
|
509
|
-
// }
|
|
510
|
-
// else
|
|
511
|
-
// rm = this._lightmaps[i];
|
|
512
|
-
// rm.init(this.lightmapIndex, this.lightmapScaleOffset, tex);
|
|
513
|
-
// }
|
|
514
|
-
// }
|
|
515
|
-
// }
|
|
516
488
|
}
|
|
517
489
|
else {
|
|
518
|
-
if (debugRenderer) console.warn(
|
|
490
|
+
if (debugRenderer) console.warn(`[Renderer] No lightmaps found ${this.name} (${this.sourceId}, ${this.lightmapIndex})`);
|
|
519
491
|
}
|
|
520
492
|
}
|
|
521
493
|
|
|
@@ -9,9 +9,17 @@ const debug = getParam("debuglightmaps");
|
|
|
9
9
|
|
|
10
10
|
declare type MaterialWithLightmap = Material & { lightMap?: Texture | null };
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
let cloningCounter = 0;
|
|
13
|
+
|
|
14
|
+
const $lightmapVersion = Symbol("lightmap-material-version");
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* This component is automatically added by the {@link Renderer} component if the object has lightmap uvs AND we have a lightmap.
|
|
19
|
+
*
|
|
20
|
+
* @category Rendering
|
|
21
|
+
* @group Components
|
|
22
|
+
*/
|
|
15
23
|
export class RendererLightmap {
|
|
16
24
|
|
|
17
25
|
get lightmap(): Texture | null {
|
|
@@ -33,6 +41,8 @@ export class RendererLightmap {
|
|
|
33
41
|
private lightmapScaleOffset: Vector4 = new Vector4(1, 1, 0, 0);
|
|
34
42
|
|
|
35
43
|
private readonly renderer: Renderer;
|
|
44
|
+
private readonly clonedMaterials = new Array<Material>();
|
|
45
|
+
|
|
36
46
|
private get context(): Context { return this.renderer.context; }
|
|
37
47
|
private get gameObject() { return this.renderer.gameObject; }
|
|
38
48
|
private lightmapTexture: Texture | null = null;
|
|
@@ -85,8 +95,7 @@ export class RendererLightmap {
|
|
|
85
95
|
|
|
86
96
|
const mat = this.renderer.sharedMaterials[i];
|
|
87
97
|
if (!mat) continue;
|
|
88
|
-
|
|
89
|
-
const newMat = this.ensureLightmapMaterial(mat);
|
|
98
|
+
const newMat = this.ensureLightmapMaterial(mat, i);
|
|
90
99
|
if (mat !== newMat) {
|
|
91
100
|
this.renderer.sharedMaterials[i] = newMat;
|
|
92
101
|
}
|
|
@@ -114,23 +123,28 @@ export class RendererLightmap {
|
|
|
114
123
|
}
|
|
115
124
|
}
|
|
116
125
|
|
|
117
|
-
private ensureLightmapMaterial(material: Material) {
|
|
126
|
+
private ensureLightmapMaterial(material: Material, index: number) {
|
|
118
127
|
if (!material.userData) material.userData = {};
|
|
119
128
|
// if (material instanceof MeshPhysicalMaterial) {
|
|
120
129
|
// return material;
|
|
121
130
|
// }
|
|
122
131
|
// check if the material version has changed and only then clone the material
|
|
123
|
-
if (
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
// we need to clone the material
|
|
132
|
+
if (this.clonedMaterials[index] !== material) {
|
|
133
|
+
if (debug) {
|
|
134
|
+
++cloningCounter;
|
|
135
|
+
if (cloningCounter++ < 1000) {
|
|
136
|
+
console.warn(`Cloning material for lightmap ${this.renderer.name}: '${material.name}'`);
|
|
137
|
+
}
|
|
138
|
+
else if (cloningCounter === 1000) {
|
|
139
|
+
console.warn(`Further material cloning for lightmaps suppressed to avoid flooding the console.`);
|
|
140
|
+
}
|
|
133
141
|
}
|
|
142
|
+
const mat: Material = material.clone();
|
|
143
|
+
if (!mat.name?.includes("(lightmap)")) mat.name = material.name + " (lightmap)";
|
|
144
|
+
material = mat;
|
|
145
|
+
material.onBeforeCompile = this.onBeforeCompile;
|
|
146
|
+
this.clonedMaterials[index] = material;
|
|
147
|
+
|
|
134
148
|
}
|
|
135
149
|
return material;
|
|
136
150
|
}
|
|
@@ -140,22 +154,22 @@ export class RendererLightmap {
|
|
|
140
154
|
if (material instanceof MeshPhysicalMaterial && material.transmission > 0) {
|
|
141
155
|
return;
|
|
142
156
|
}
|
|
143
|
-
const hasChanged = material.lightMap !== this.lightmapTexture || material[
|
|
157
|
+
const hasChanged = material.lightMap !== this.lightmapTexture || material[$lightmapVersion] !== material.version;
|
|
144
158
|
if (!hasChanged) {
|
|
145
159
|
return;
|
|
146
160
|
}
|
|
147
161
|
|
|
148
|
-
if (debug) console.log(
|
|
162
|
+
if (debug) console.log(`Assigning lightmap texture ${this.renderer.name}: '${material.name}' (${material.version} ${material[$lightmapVersion]})`);
|
|
149
163
|
|
|
150
164
|
// assign the lightmap
|
|
151
165
|
material.lightMap = this.lightmapTexture;
|
|
152
166
|
material.needsUpdate = true;
|
|
153
167
|
// store the version of the material
|
|
154
|
-
material[
|
|
168
|
+
material[$lightmapVersion] = material.version;
|
|
155
169
|
}
|
|
156
170
|
|
|
157
171
|
private onBeforeCompile = (shader: WebGLProgramParametersWithUniforms, _) => {
|
|
158
|
-
if (debug) console.log("Lightmaps, before compile\n", shader)
|
|
172
|
+
if (debug === "verbose") console.log("Lightmaps, before compile\n", shader)
|
|
159
173
|
this.lightmapScaleOffsetUniform.value = this.lightmapScaleOffset;
|
|
160
174
|
this.lightmapUniform.value = this.lightmapTexture;
|
|
161
175
|
shader.uniforms.lightmapScaleOffset = this.lightmapScaleOffsetUniform;
|
|
@@ -39,6 +39,9 @@ let i = 0;
|
|
|
39
39
|
* Requires a Renderer component on the same object or a child object.
|
|
40
40
|
*
|
|
41
41
|
* - Example https://see-through-walls-z23hmxbz1kjfjn.needle.run/
|
|
42
|
+
*
|
|
43
|
+
* @category Rendering
|
|
44
|
+
* @group Components
|
|
42
45
|
*/
|
|
43
46
|
export class SeeThrough extends Behaviour {
|
|
44
47
|
|
|
@@ -120,6 +120,9 @@ ContextRegistry.registerCallback(ContextEvent.ContextCreationStart, () => {
|
|
|
120
120
|
* ```ts
|
|
121
121
|
* skybox.setSkybox("https://example.com/skybox.hdr");
|
|
122
122
|
* ```
|
|
123
|
+
*
|
|
124
|
+
* @category Rendering
|
|
125
|
+
* @group Components
|
|
123
126
|
*/
|
|
124
127
|
export class RemoteSkybox extends Behaviour {
|
|
125
128
|
|
|
@@ -9,6 +9,9 @@ import { Behaviour } from "./Component.js";
|
|
|
9
9
|
const debug = getParam("debugspriterenderer");
|
|
10
10
|
const showWireframe = getParam("wireframe");
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
12
15
|
class SpriteUtils {
|
|
13
16
|
|
|
14
17
|
static cache: { [key: string]: BufferGeometry } = {};
|
|
@@ -82,7 +85,7 @@ function updateTextureIfNecessary(tex: Texture) {
|
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
/**
|
|
85
|
-
* A sprite is a mesh that represents a 2D image
|
|
88
|
+
* A sprite is a mesh that represents a 2D image. Used by the {@link SpriteRenderer} to render 2D images in the scene.
|
|
86
89
|
* @category Rendering
|
|
87
90
|
* @group Components
|
|
88
91
|
*/
|
|
@@ -152,6 +155,9 @@ export class Sprite {
|
|
|
152
155
|
|
|
153
156
|
const $spriteTexOwner = Symbol("spriteOwner");
|
|
154
157
|
|
|
158
|
+
/**
|
|
159
|
+
* @category Sprites
|
|
160
|
+
*/
|
|
155
161
|
export class SpriteSheet {
|
|
156
162
|
|
|
157
163
|
@serializable(Sprite)
|
|
@@ -162,6 +168,11 @@ export class SpriteSheet {
|
|
|
162
168
|
}
|
|
163
169
|
}
|
|
164
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Used by the {@link SpriteRenderer} to hold the sprite sheet and the currently active sprite index.
|
|
173
|
+
*
|
|
174
|
+
* @category Sprites
|
|
175
|
+
*/
|
|
165
176
|
export class SpriteData {
|
|
166
177
|
|
|
167
178
|
static create() {
|
|
@@ -246,7 +257,12 @@ export class SpriteData {
|
|
|
246
257
|
}
|
|
247
258
|
|
|
248
259
|
/**
|
|
249
|
-
* The sprite renderer renders a sprite on a GameObject using an assigned spritesheet ({@link SpriteData}).
|
|
260
|
+
* The sprite renderer renders a sprite on a GameObject using an assigned spritesheet ({@link SpriteData}).
|
|
261
|
+
*
|
|
262
|
+
* - Example: https://engine.needle.tools/samples/spritesheet-animation
|
|
263
|
+
*
|
|
264
|
+
* @category Sprites
|
|
265
|
+
* @group Components
|
|
250
266
|
*/
|
|
251
267
|
export class SpriteRenderer extends Behaviour {
|
|
252
268
|
|
|
@@ -36,6 +36,9 @@ export class SplineData {
|
|
|
36
36
|
* The spline is defined by an array of knots (SplineData) which define position, rotation and tangents.
|
|
37
37
|
*
|
|
38
38
|
* You can create a SplineContainer from an array of points using the static method 'createFromPoints'.
|
|
39
|
+
*
|
|
40
|
+
* @category Splines
|
|
41
|
+
* @group Components
|
|
39
42
|
*/
|
|
40
43
|
export class SplineContainer extends Behaviour {
|
|
41
44
|
|
|
@@ -11,6 +11,9 @@ import { SplineContainer } from "./Spline.js";
|
|
|
11
11
|
* Use this with a SplineContainer component.
|
|
12
12
|
*
|
|
13
13
|
* - Example http://samples.needle.tools/splines
|
|
14
|
+
*
|
|
15
|
+
* @category Splines
|
|
16
|
+
* @group Components
|
|
14
17
|
*/
|
|
15
18
|
export class SplineWalker extends Behaviour {
|
|
16
19
|
|
|
@@ -114,8 +114,7 @@ export class PlayableDirector extends Behaviour {
|
|
|
114
114
|
|
|
115
115
|
/** @internal */
|
|
116
116
|
awake(): void {
|
|
117
|
-
if (debug)
|
|
118
|
-
console.log(this, this.playableAsset);
|
|
117
|
+
if (debug) console.log(`[Timeline] Awake '${this.name}'`, this);
|
|
119
118
|
|
|
120
119
|
this.rebuildGraph();
|
|
121
120
|
|
|
@@ -134,6 +133,8 @@ export class PlayableDirector extends Behaviour {
|
|
|
134
133
|
|
|
135
134
|
/** @internal */
|
|
136
135
|
onEnable() {
|
|
136
|
+
if (debug) console.log("[Timeline] OnEnable", this.name, this.playOnAwake);
|
|
137
|
+
|
|
137
138
|
for (const track of this._audioTracks) {
|
|
138
139
|
track.onEnable?.();
|
|
139
140
|
}
|
|
@@ -162,6 +163,8 @@ export class PlayableDirector extends Behaviour {
|
|
|
162
163
|
|
|
163
164
|
/** @internal */
|
|
164
165
|
onDisable(): void {
|
|
166
|
+
if (debug) console.log("[Timeline] OnDisable", this.name);
|
|
167
|
+
|
|
165
168
|
this.stop();
|
|
166
169
|
for (const track of this._audioTracks) {
|
|
167
170
|
track.onDisable?.();
|
|
@@ -360,14 +363,17 @@ export class PlayableDirector extends Behaviour {
|
|
|
360
363
|
private readonly _controlTracks: Array<Tracks.ControlTrackHandler> = [];
|
|
361
364
|
private readonly _customTracks: Array<Tracks.TrackHandler> = [];
|
|
362
365
|
|
|
363
|
-
private readonly
|
|
364
|
-
|
|
365
|
-
this.
|
|
366
|
-
this.
|
|
367
|
-
this.
|
|
368
|
-
this.
|
|
369
|
-
this.
|
|
370
|
-
|
|
366
|
+
private readonly _tracksArray: Array<Array<Tracks.TrackHandler>> = [];
|
|
367
|
+
private get _allTracks(): Array<Array<Tracks.TrackHandler>> {
|
|
368
|
+
this._tracksArray.length = 0;
|
|
369
|
+
this._tracksArray.push(this._animationTracks);
|
|
370
|
+
this._tracksArray.push(this._audioTracks);
|
|
371
|
+
this._tracksArray.push(this._signalTracks);
|
|
372
|
+
this._tracksArray.push(this._markerTracks);
|
|
373
|
+
this._tracksArray.push(this._controlTracks);
|
|
374
|
+
this._tracksArray.push(this._customTracks);
|
|
375
|
+
return this._tracksArray;
|
|
376
|
+
}
|
|
371
377
|
|
|
372
378
|
/** should be called after evaluate if the director was playing */
|
|
373
379
|
private invokePauseChangedMethodsOnTracks() {
|