@needle-tools/engine 4.8.8-next.5cb3196 → 4.8.8-next.68a4ed9
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/components.needle.json +1 -1
- package/dist/{needle-engine.bundle-DJA-sz_-.js → needle-engine.bundle-DC3b3Kq9.js} +2014 -1985
- package/dist/{needle-engine.bundle-SWdTk441.min.js → needle-engine.bundle-Dh2Fn0ZZ.min.js} +95 -95
- package/dist/{needle-engine.bundle-D83YACrg.umd.cjs → needle-engine.bundle-DrstVBTv.umd.cjs} +100 -100
- package/dist/needle-engine.d.ts +7 -0
- package/dist/needle-engine.js +2 -2
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/engine_addressables.js +2 -0
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_animation.js +4 -4
- package/lib/engine/engine_animation.js.map +1 -1
- package/lib/engine/engine_assetdatabase.js +6 -6
- package/lib/engine/engine_assetdatabase.js.map +1 -1
- package/lib/engine/engine_camera.d.ts +3 -0
- package/lib/engine/engine_camera.js.map +1 -1
- package/lib/engine/engine_context.d.ts +8 -2
- package/lib/engine/engine_context.js +21 -3
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_create_objects.d.ts +3 -3
- package/lib/engine/engine_create_objects.js +5 -4
- package/lib/engine/engine_create_objects.js.map +1 -1
- package/lib/engine/engine_gameobject.js +2 -2
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_gltf_builtin_components.js +11 -11
- package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_lighting_settings.js +5 -2
- package/lib/engine/extensions/NEEDLE_lighting_settings.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_lightmaps.js +1 -1
- package/lib/engine/extensions/NEEDLE_lightmaps.js.map +1 -1
- package/lib/engine/js-extensions/Object3D.d.ts +1 -1
- package/lib/engine/js-extensions/Vector.d.ts +5 -0
- package/lib/engine/js-extensions/Vector.js.map +1 -1
- package/lib/engine-components/ContactShadows.d.ts +12 -2
- package/lib/engine-components/ContactShadows.js +24 -4
- package/lib/engine-components/ContactShadows.js.map +1 -1
- package/lib/engine-components/NestedGltf.d.ts +9 -4
- package/lib/engine-components/NestedGltf.js +32 -26
- package/lib/engine-components/NestedGltf.js.map +1 -1
- package/lib/engine-components/Renderer.js +2 -1
- package/lib/engine-components/Renderer.js.map +1 -1
- package/package.json +1 -1
- package/plugins/common/files.js +6 -3
- package/src/engine/engine_addressables.ts +2 -0
- package/src/engine/engine_animation.ts +4 -4
- package/src/engine/engine_assetdatabase.ts +7 -7
- package/src/engine/engine_camera.ts +3 -1
- package/src/engine/engine_context.ts +22 -4
- package/src/engine/engine_create_objects.ts +8 -7
- package/src/engine/engine_gameobject.ts +2 -2
- package/src/engine/engine_gltf_builtin_components.ts +12 -11
- package/src/engine/extensions/NEEDLE_lighting_settings.ts +5 -2
- package/src/engine/extensions/NEEDLE_lightmaps.ts +1 -1
- package/src/engine/js-extensions/Vector.ts +6 -0
- package/src/engine-components/ContactShadows.ts +27 -6
- package/src/engine-components/NestedGltf.ts +33 -24
- package/src/engine-components/Renderer.ts +2 -1
|
@@ -120,7 +120,7 @@ export class AnimationUtils {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
let animationComponent =
|
|
123
|
+
let animationComponent = findAnimationComponentInParent(obj) || findAnimationComponentInParent(scene);
|
|
124
124
|
if (!animationComponent) {
|
|
125
125
|
const anim = TypeStore.get("Animation");
|
|
126
126
|
animationComponent = scene.addComponent(anim);
|
|
@@ -137,18 +137,18 @@ export class AnimationUtils {
|
|
|
137
137
|
}
|
|
138
138
|
return animationComponents;
|
|
139
139
|
|
|
140
|
-
function
|
|
140
|
+
function findAnimationComponentInParent(obj): IAnimationComponent | null {
|
|
141
141
|
if (!obj) return null;
|
|
142
142
|
const components = obj.userData?.components;
|
|
143
143
|
if (components && components.length > 0) {
|
|
144
144
|
for (let i = 0; i < components.length; i++) {
|
|
145
145
|
const component = components[i] as IAnimationComponent;
|
|
146
146
|
if (component.isAnimationComponent === true) {
|
|
147
|
-
return
|
|
147
|
+
return component;
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
|
-
return
|
|
151
|
+
return findAnimationComponentInParent(obj.parent);
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -61,7 +61,7 @@ export function disposeObjectResources(obj: object | null | undefined) {
|
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
if(typeof obj === "object") {
|
|
64
|
+
if (typeof obj === "object") {
|
|
65
65
|
obj[$disposed] = true;
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -79,8 +79,8 @@ export function disposeObjectResources(obj: object | null | undefined) {
|
|
|
79
79
|
disposeObjectResources(obj.bindMatrixInverse);
|
|
80
80
|
disposeObjectResources(obj.customDepthMaterial);
|
|
81
81
|
disposeObjectResources(obj.customDistanceMaterial);
|
|
82
|
-
obj.geometry =
|
|
83
|
-
obj.material =
|
|
82
|
+
obj.geometry = {};
|
|
83
|
+
obj.material = {};
|
|
84
84
|
obj.visible = false;
|
|
85
85
|
}
|
|
86
86
|
else if (obj instanceof Mesh) {
|
|
@@ -88,8 +88,8 @@ export function disposeObjectResources(obj: object | null | undefined) {
|
|
|
88
88
|
disposeObjectResources(obj.material);
|
|
89
89
|
disposeObjectResources(obj.customDepthMaterial);
|
|
90
90
|
disposeObjectResources(obj.customDistanceMaterial);
|
|
91
|
-
obj.geometry =
|
|
92
|
-
obj.material =
|
|
91
|
+
obj.geometry = {};
|
|
92
|
+
obj.material = {};
|
|
93
93
|
obj.visible = false;
|
|
94
94
|
}
|
|
95
95
|
else if (obj instanceof BufferGeometry) {
|
|
@@ -175,8 +175,8 @@ function free(obj: any) {
|
|
|
175
175
|
|
|
176
176
|
export function __internalNotifyObjectDestroyed(obj: Object3D) {
|
|
177
177
|
if (obj instanceof Mesh || obj instanceof SkinnedMesh) {
|
|
178
|
-
obj.material =
|
|
179
|
-
obj.geometry =
|
|
178
|
+
obj.material = {};
|
|
179
|
+
obj.geometry = {};
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
@@ -42,7 +42,9 @@ export function setAutoFitEnabled(obj: Object3D, enabled: boolean): void {
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
export type FocusRectSettings = {
|
|
46
|
+
damping: number
|
|
47
|
+
}
|
|
46
48
|
export type FocusRect = DOMRect | Element | { x: number, y: number, width: number, height: number };
|
|
47
49
|
|
|
48
50
|
let rendererRect: DOMRect | undefined = undefined;
|
|
@@ -18,7 +18,7 @@ import { Addressables } from './engine_addressables.js';
|
|
|
18
18
|
import { AnimationsRegistry } from './engine_animation.js';
|
|
19
19
|
import { Application } from './engine_application.js';
|
|
20
20
|
import { AssetDatabase } from './engine_assetdatabase.js';
|
|
21
|
-
import { FocusRect, updateCameraFocusRect } from './engine_camera.js';
|
|
21
|
+
import { FocusRect, FocusRectSettings, updateCameraFocusRect } from './engine_camera.js';
|
|
22
22
|
import { VERSION } from './engine_constants.js';
|
|
23
23
|
import { ContextEvent, ContextRegistry } from './engine_context_registry.js';
|
|
24
24
|
import { WaitForPromise } from './engine_coroutine.js';
|
|
@@ -1378,11 +1378,26 @@ export class Context implements IContext {
|
|
|
1378
1378
|
* Set a rect or dom element. The camera center will be moved to the center of the rect.
|
|
1379
1379
|
* This is useful if you have Needle Engine embedded in a HTML layout and while you want the webgl background to fill e.g. the whole screen you want to move the camera center to free space.
|
|
1380
1380
|
* For that you can simply pass in the rect or HMTL div that you want the camera to center on.
|
|
1381
|
+
* @param rect The focus rect or null to disable
|
|
1382
|
+
* @param settings Optional settings for the focus rect. These will override the `focusRectSettings` property
|
|
1381
1383
|
*/
|
|
1382
|
-
public setCameraFocusRect(rect: FocusRect | null) {
|
|
1384
|
+
public setCameraFocusRect(rect: FocusRect | null, settings?: Partial<FocusRectSettings>) {
|
|
1383
1385
|
this._focusRect = rect;
|
|
1386
|
+
if (settings) {
|
|
1387
|
+
Object.assign(this.focusRectSettings, settings);
|
|
1388
|
+
}
|
|
1384
1389
|
}
|
|
1385
1390
|
get focusRect() { return this._focusRect; }
|
|
1391
|
+
/** Settings when a focus rect is set. Use `setCameraFocusRect(...)` to do so.
|
|
1392
|
+
* This can be used to offset the renderer center e.g. to a specific DOM element.
|
|
1393
|
+
*/
|
|
1394
|
+
readonly focusRectSettings: FocusRectSettings = {
|
|
1395
|
+
/** Controls how fast the rect is centered. Smaller values mean the rect is centered faster.
|
|
1396
|
+
* A minimum value of 0 means the rect is centered instantly.
|
|
1397
|
+
* @default .05
|
|
1398
|
+
*/
|
|
1399
|
+
damping: .05
|
|
1400
|
+
};
|
|
1386
1401
|
private _focusRect: FocusRect | null = null;
|
|
1387
1402
|
|
|
1388
1403
|
|
|
@@ -1514,8 +1529,11 @@ export class Context implements IContext {
|
|
|
1514
1529
|
if (this.isVisibleToUser || this.runInBackground) {
|
|
1515
1530
|
|
|
1516
1531
|
if (this._focusRect) {
|
|
1517
|
-
if (this.mainCamera instanceof PerspectiveCamera)
|
|
1518
|
-
|
|
1532
|
+
if (this.mainCamera instanceof PerspectiveCamera) {
|
|
1533
|
+
const settings = this.focusRectSettings;
|
|
1534
|
+
const dt = settings.damping > 0 ? this.time.deltaTime / settings.damping : 1;
|
|
1535
|
+
updateCameraFocusRect(this._focusRect, dt, this.mainCamera, this.renderer);
|
|
1536
|
+
}
|
|
1519
1537
|
}
|
|
1520
1538
|
|
|
1521
1539
|
this._currentFrameEvent = FrameEvent.OnBeforeRender;
|
|
@@ -42,13 +42,13 @@ export type ObjectOptions = {
|
|
|
42
42
|
/**
|
|
43
43
|
* The position of the object in local space
|
|
44
44
|
*/
|
|
45
|
-
position?: Vec3 | [number, number, number],
|
|
45
|
+
position?: Partial<Vec3> | [number, number, number],
|
|
46
46
|
/** The rotation of the object in local space */
|
|
47
|
-
rotation?: Vec3 | [number, number, number],
|
|
47
|
+
rotation?: Partial<Vec3> | [number, number, number],
|
|
48
48
|
/**
|
|
49
49
|
* The scale of the object in local space
|
|
50
50
|
*/
|
|
51
|
-
scale?: Vec3 | number | [number, number, number],
|
|
51
|
+
scale?: Partial<Vec3> | number | [number, number, number],
|
|
52
52
|
/**
|
|
53
53
|
* If the object should receive shadows
|
|
54
54
|
* @default true
|
|
@@ -251,14 +251,15 @@ export class ObjectUtils {
|
|
|
251
251
|
if (opts?.position) {
|
|
252
252
|
if (Array.isArray(opts.position))
|
|
253
253
|
obj.position.set(opts.position[0], opts.position[1], opts.position[2]);
|
|
254
|
-
else
|
|
255
|
-
obj.position.set(opts.position.x, opts.position.y, opts.position.z);
|
|
254
|
+
else {
|
|
255
|
+
obj.position.set(opts.position.x || 0, opts.position.y || 0, opts.position.z || 0);
|
|
256
|
+
}
|
|
256
257
|
}
|
|
257
258
|
if (opts?.rotation) {
|
|
258
259
|
if (Array.isArray(opts.rotation))
|
|
259
260
|
obj.rotation.set(opts.rotation[0], opts.rotation[1], opts.rotation[2]);
|
|
260
261
|
else
|
|
261
|
-
obj.rotation.set(opts.rotation.x, opts.rotation.y, opts.rotation.z);
|
|
262
|
+
obj.rotation.set(opts.rotation.x || 0, opts.rotation.y || 0, opts.rotation.z || 0);
|
|
262
263
|
}
|
|
263
264
|
if (opts?.scale) {
|
|
264
265
|
if (typeof opts.scale === "number")
|
|
@@ -267,7 +268,7 @@ export class ObjectUtils {
|
|
|
267
268
|
obj.scale.set(opts.scale[0], opts.scale[1], opts.scale[2]);
|
|
268
269
|
}
|
|
269
270
|
else {
|
|
270
|
-
obj.scale.set(opts.scale.x, opts.scale.y, opts.scale.z);
|
|
271
|
+
obj.scale.set(opts.scale.x || 1, opts.scale.y || 1, opts.scale.z || 1);
|
|
271
272
|
|
|
272
273
|
}
|
|
273
274
|
}
|
|
@@ -166,9 +166,9 @@ export function destroy(instance: Object3D | Component, recursive: boolean = tru
|
|
|
166
166
|
setDestroyed(obj, true);
|
|
167
167
|
if (dispose) {
|
|
168
168
|
disposeObjectResources(obj);
|
|
169
|
+
// This needs to be called after disposing because it removes the references to resources
|
|
170
|
+
__internalRemoveReferences(obj);
|
|
169
171
|
}
|
|
170
|
-
// This needs to be called after disposing because it removes the references to resources
|
|
171
|
-
__internalRemoveReferences(obj);
|
|
172
172
|
}
|
|
173
173
|
destroyed_objects.length = 0;
|
|
174
174
|
destroyed_components.length = 0;
|
|
@@ -72,13 +72,13 @@ export async function createBuiltinComponents(context: Context, gltfId: SourceId
|
|
|
72
72
|
|
|
73
73
|
if (gltf.scenes) {
|
|
74
74
|
for (const scene of gltf.scenes) {
|
|
75
|
-
await onCreateBuiltinComponents(serializationContext, scene, deserializeQueue, lateResolve);
|
|
75
|
+
await onCreateBuiltinComponents(serializationContext, scene, deserializeQueue, lateResolve, 0);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
// TODO: when is the gltf here an object3d?
|
|
79
79
|
if (gltf.children) {
|
|
80
80
|
for (const ch of gltf.children) {
|
|
81
|
-
await onCreateBuiltinComponents(serializationContext, ch, deserializeQueue, lateResolve);
|
|
81
|
+
await onCreateBuiltinComponents(serializationContext, ch, deserializeQueue, lateResolve, 0);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -202,7 +202,7 @@ const unknownComponentsBuffer: Array<string> = [];
|
|
|
202
202
|
|
|
203
203
|
|
|
204
204
|
async function onCreateBuiltinComponents(context: SerializationContext, obj: Object3D,
|
|
205
|
-
deserialize: DeserializeData[], lateResolve: LateResolveCallback[]) {
|
|
205
|
+
deserialize: DeserializeData[], lateResolve: LateResolveCallback[], level: number) {
|
|
206
206
|
if (!obj) return;
|
|
207
207
|
|
|
208
208
|
// iterate injected data
|
|
@@ -267,20 +267,21 @@ async function onCreateBuiltinComponents(context: SerializationContext, obj: Obj
|
|
|
267
267
|
}
|
|
268
268
|
// console.debug("finished adding gltf builtin components", obj);
|
|
269
269
|
}
|
|
270
|
-
if (unknownComponentsBuffer.length > 0) {
|
|
271
|
-
const unknown = unknownComponentsBuffer.join(", ");
|
|
272
|
-
console.warn("unknown components: " + unknown);
|
|
273
|
-
unknownComponentsBuffer.length = 0;
|
|
274
|
-
if (isLocalNetwork())
|
|
275
|
-
showBalloonMessage(`<strong>Unknown components in scene</strong>:\n\n${unknown}\n\nThis could mean you forgot to add a npmdef to your ExportInfo\n<a href="https://engine.needle.tools/docs/project_structure.html#creating-and-installing-a-npmdef" target="_blank">documentation</a>`, LogType.Warn);
|
|
276
|
-
}
|
|
277
270
|
}
|
|
278
271
|
|
|
279
272
|
if (obj.children) {
|
|
280
273
|
for (const ch of obj.children) {
|
|
281
|
-
await onCreateBuiltinComponents(context, ch, deserialize, lateResolve);
|
|
274
|
+
await onCreateBuiltinComponents(context, ch, deserialize, lateResolve, level + 1);
|
|
282
275
|
}
|
|
283
276
|
}
|
|
277
|
+
|
|
278
|
+
if (unknownComponentsBuffer.length > 0 && level === 0) {
|
|
279
|
+
const unknown = unknownComponentsBuffer.join(", ");
|
|
280
|
+
console.warn(`Unknown components in scene: ${unknown}`);
|
|
281
|
+
unknownComponentsBuffer.length = 0;
|
|
282
|
+
if (isLocalNetwork())
|
|
283
|
+
showBalloonMessage(`<strong>Unknown components in scene</strong>:\n\n${unknown}\n\nThis could mean you forgot to add a npmdef to your ExportInfo\n<a href="https://engine.needle.tools/docs/project_structure.html#creating-and-installing-a-npmdef" target="_blank">documentation</a>`, LogType.Warn);
|
|
284
|
+
}
|
|
284
285
|
}
|
|
285
286
|
|
|
286
287
|
function handleDeserialization(data: DeserializeData, context: SerializationContext) {
|
|
@@ -169,8 +169,11 @@ export class SceneLightSettings extends Behaviour {
|
|
|
169
169
|
this._hemisphereLightObj.removeFromParent();
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
if (this.sourceId)
|
|
173
|
-
this.context.
|
|
172
|
+
if (this.sourceId) {
|
|
173
|
+
if (!this.context.domElement.getAttribute("environment-image")) {
|
|
174
|
+
this.context.sceneLighting.internalEnableReflection(this.sourceId);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
174
177
|
}
|
|
175
178
|
|
|
176
179
|
onDisable() {
|
|
@@ -70,7 +70,7 @@ export class NEEDLE_lightmaps implements GLTFLoaderPlugin {
|
|
|
70
70
|
console.log(entry);
|
|
71
71
|
let res: Promise<any> | null = null;
|
|
72
72
|
// Check if the pointer is a json pointer:
|
|
73
|
-
if (entry.pointer.startsWith("/textures/")) {
|
|
73
|
+
if (entry.pointer.startsWith("/textures/") || /** legacy support e.g. SOC */entry.pointer.startsWith("textures/")) {
|
|
74
74
|
if (debug) console.log("Load texture from gltf", entry.pointer);
|
|
75
75
|
res = resolveReferences(this.parser, entry.pointer).then(res => this.resolveTexture(entry, res));
|
|
76
76
|
}
|
|
@@ -10,6 +10,12 @@ export function apply(object: Vector3) {
|
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
// NOTE: keep in sync with method declarations below
|
|
14
|
+
declare module 'three' {
|
|
15
|
+
export interface Vector3 {
|
|
16
|
+
slerp(end: Vector3, t: number): Vector3;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
13
19
|
|
|
14
20
|
Vector3.prototype["slerp"] = function (end: Vector3, t: number) {
|
|
15
21
|
return slerp(this, end, t);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BackSide, CustomBlending, DoubleSide, FrontSide, Group, Material, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshStandardMaterial, MinEquation, Object3D, OrthographicCamera, PlaneGeometry, RenderItem, ShaderMaterial, Vector3, WebGLRenderTarget } from "three";
|
|
1
|
+
import { BackSide, CustomBlending, DoubleSide, FrontSide, Group, Material, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshStandardMaterial, MinEquation, Object3D, OrthographicCamera, PlaneGeometry, RenderItem, ShaderMaterial, Vector3, Vector3Like, WebGLRenderTarget } from "three";
|
|
2
2
|
import { HorizontalBlurShader } from 'three/examples/jsm/shaders/HorizontalBlurShader.js';
|
|
3
3
|
import { VerticalBlurShader } from 'three/examples/jsm/shaders/VerticalBlurShader.js';
|
|
4
4
|
|
|
@@ -27,7 +27,14 @@ onStart(ctx => {
|
|
|
27
27
|
shadows.darkness = intensity;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
})
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
type FitParameters = {
|
|
34
|
+
object?: Object3D | Object3D[];
|
|
35
|
+
positionOffset?: Partial<Vector3Like>;
|
|
36
|
+
scaleFactor?: Partial<Vector3Like>;
|
|
37
|
+
}
|
|
31
38
|
|
|
32
39
|
// Adapted from https://github.com/mrdoob/three.js/blob/master/examples/webgl_shadow_contact.html.
|
|
33
40
|
|
|
@@ -50,7 +57,7 @@ export class ContactShadows extends Behaviour {
|
|
|
50
57
|
* @param context The context to create the contact shadows in.
|
|
51
58
|
* @returns The instance of the contact shadows.
|
|
52
59
|
*/
|
|
53
|
-
static auto(context?: Context): ContactShadows {
|
|
60
|
+
static auto(context?: Context, params?: FitParameters): ContactShadows {
|
|
54
61
|
if (!context) context = Context.Current;
|
|
55
62
|
if (!context) {
|
|
56
63
|
throw new Error("No context provided and no current context set.");
|
|
@@ -65,12 +72,13 @@ export class ContactShadows extends Behaviour {
|
|
|
65
72
|
this._instances.set(context, instance);
|
|
66
73
|
}
|
|
67
74
|
context.scene.add(instance.gameObject);
|
|
68
|
-
instance.fitShadows();
|
|
75
|
+
instance.fitShadows(params);
|
|
69
76
|
return instance;
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
/**
|
|
73
80
|
* When enabled the contact shadows component will be created to fit the whole scene.
|
|
81
|
+
* @default false
|
|
74
82
|
*/
|
|
75
83
|
@serializable()
|
|
76
84
|
autoFit: boolean = false;
|
|
@@ -107,12 +115,14 @@ export class ContactShadows extends Behaviour {
|
|
|
107
115
|
|
|
108
116
|
/**
|
|
109
117
|
* The minimum size of the shadows box
|
|
118
|
+
* @default undefined
|
|
110
119
|
*/
|
|
111
120
|
minSize?: Partial<Vec3>;
|
|
112
121
|
|
|
113
122
|
/**
|
|
114
123
|
* When enabled the shadows will not be updated automatically. Use `needsUpdate()` to update the shadows manually.
|
|
115
124
|
* This is useful when you want to update the shadows only when the scene changes.
|
|
125
|
+
* @default false
|
|
116
126
|
*/
|
|
117
127
|
manualUpdate: boolean = false;
|
|
118
128
|
/**
|
|
@@ -150,10 +160,11 @@ export class ContactShadows extends Behaviour {
|
|
|
150
160
|
/**
|
|
151
161
|
* Call to fit the shadows to the scene.
|
|
152
162
|
*/
|
|
153
|
-
fitShadows() {
|
|
163
|
+
fitShadows(params: FitParameters = {}) {
|
|
154
164
|
if (debug) console.warn("Fitting shadows to scene");
|
|
155
165
|
setAutoFitEnabled(this.shadowsRoot, false);
|
|
156
|
-
const
|
|
166
|
+
const objectToFit = params.object || this.context.scene;
|
|
167
|
+
const box = getBoundingBox(objectToFit, [this.shadowsRoot]);
|
|
157
168
|
// expand box in all directions (except below ground)
|
|
158
169
|
// 0.75 expands by 75% in each direction
|
|
159
170
|
// The "32" is pretty much heuristically determined – adjusting the value until we don't get a visible border anymore.
|
|
@@ -175,6 +186,16 @@ export class ContactShadows extends Behaviour {
|
|
|
175
186
|
// We can't move GroundProjection down because of immersive-ar mesh/plane tracking where occlusion would otherwise hide GroundProjection
|
|
176
187
|
this.shadowsRoot.position.set((min.x + box.max.x) / 2, min.y - offset, (min.z + box.max.z) / 2);
|
|
177
188
|
this.shadowsRoot.scale.set(box.max.x - min.x, box.max.y - min.y, box.max.z - min.z);
|
|
189
|
+
if (params.positionOffset) {
|
|
190
|
+
if (params.positionOffset.x !== undefined) this.shadowsRoot.position.x += params.positionOffset.x;
|
|
191
|
+
if (params.positionOffset.y !== undefined) this.shadowsRoot.position.y += params.positionOffset.y;
|
|
192
|
+
if (params.positionOffset.z !== undefined) this.shadowsRoot.position.z += params.positionOffset.z;
|
|
193
|
+
}
|
|
194
|
+
if (params.scaleFactor) {
|
|
195
|
+
if (params.scaleFactor.x !== undefined) this.shadowsRoot.scale.x *= params.scaleFactor.x;
|
|
196
|
+
if (params.scaleFactor.y !== undefined) this.shadowsRoot.scale.y *= params.scaleFactor.y;
|
|
197
|
+
if (params.scaleFactor.z !== undefined) this.shadowsRoot.scale.z *= params.scaleFactor.z;
|
|
198
|
+
}
|
|
178
199
|
this.applyMinSize();
|
|
179
200
|
this.shadowsRoot.matrixWorldNeedsUpdate = true;
|
|
180
201
|
if (debug) console.log("Fitted shadows to scene", this.shadowsRoot.scale.clone());
|
|
@@ -4,6 +4,7 @@ import { InstantiateIdProvider } from "../engine/engine_networking_instantiate.j
|
|
|
4
4
|
import { serializable } from "../engine/engine_serialization_decorator.js";
|
|
5
5
|
import { getParam } from "../engine/engine_utils.js";
|
|
6
6
|
import { Behaviour } from "../engine-components/Component.js";
|
|
7
|
+
import { EventList } from "./EventList.js";
|
|
7
8
|
|
|
8
9
|
const debug = getParam("debugnestedgltf");
|
|
9
10
|
|
|
@@ -11,17 +12,21 @@ const debug = getParam("debugnestedgltf");
|
|
|
11
12
|
* It will load the gltf file and instantiate it as a child of the parent of the GameObject that has this component
|
|
12
13
|
*/
|
|
13
14
|
export class NestedGltf extends Behaviour {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*/
|
|
15
|
+
|
|
16
|
+
/** A reference to the gltf file that should be loaded */
|
|
17
17
|
@serializable(AssetReference)
|
|
18
18
|
filePath?: AssetReference;
|
|
19
19
|
|
|
20
|
+
/** Invoked when the nested glTF file has been instantiated */
|
|
21
|
+
@serializable(EventList)
|
|
22
|
+
loaded: EventList<{ component: NestedGltf, instance: any, asset: AssetReference }> = new EventList();
|
|
23
|
+
|
|
20
24
|
/**
|
|
21
25
|
* EXPERIMENTAL for cloud asset loading
|
|
22
26
|
*/
|
|
23
27
|
loadAssetInParent = true;
|
|
24
28
|
|
|
29
|
+
|
|
25
30
|
private _isLoadingOrDoneLoading: boolean = false;
|
|
26
31
|
|
|
27
32
|
/** Register a callback that will be called when the progress of the loading changes */
|
|
@@ -31,7 +36,7 @@ export class NestedGltf extends Behaviour {
|
|
|
31
36
|
|
|
32
37
|
/** Begin loading the referenced gltf file in filePath */
|
|
33
38
|
preload() {
|
|
34
|
-
this.filePath?.preload();
|
|
39
|
+
return this.filePath?.preload() || null;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
/** @internal */
|
|
@@ -41,27 +46,31 @@ export class NestedGltf extends Behaviour {
|
|
|
41
46
|
|
|
42
47
|
const parent = this.gameObject.parent;
|
|
43
48
|
if (parent) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
res
|
|
56
|
-
|
|
57
|
-
res.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
49
|
+
|
|
50
|
+
if (this.filePath) {
|
|
51
|
+
|
|
52
|
+
this._isLoadingOrDoneLoading = true;
|
|
53
|
+
const opts = new InstantiateOptions();
|
|
54
|
+
// we need to provide stable guids for creating nested gltfs
|
|
55
|
+
opts.idProvider = new InstantiateIdProvider(this.hash(this.guid));
|
|
56
|
+
opts.parent = this.loadAssetInParent !== false ? parent : this.gameObject;
|
|
57
|
+
this.gameObject.updateMatrix();
|
|
58
|
+
const matrix = this.gameObject.matrix;
|
|
59
|
+
if (debug) console.log("Load nested:", this.filePath?.url ?? this.filePath, this.gameObject.position);
|
|
60
|
+
const res = await this.filePath?.instantiate?.call(this.filePath, opts);
|
|
61
|
+
if (debug) console.log("Nested loaded:", this.filePath?.url ?? this.filePath, res);
|
|
62
|
+
if (res && this.loadAssetInParent !== false) {
|
|
63
|
+
res.matrixAutoUpdate = false;
|
|
64
|
+
res.matrix.identity();
|
|
65
|
+
res.applyMatrix4(matrix);
|
|
66
|
+
res.matrixAutoUpdate = true;
|
|
67
|
+
res.layers.disableAll();
|
|
68
|
+
res.layers.set(this.layer);
|
|
69
|
+
this.loaded.invoke({ component: this, instance: res, asset: this.filePath });
|
|
70
|
+
}
|
|
71
|
+
if (debug) console.log("Nested loading done:", this.filePath?.url ?? this.filePath, res);
|
|
63
72
|
}
|
|
64
|
-
|
|
73
|
+
|
|
65
74
|
}
|
|
66
75
|
}
|
|
67
76
|
|
|
@@ -706,7 +706,8 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
706
706
|
}
|
|
707
707
|
|
|
708
708
|
if (this.reflectionProbeUsage !== ReflectionProbeUsage.Off && this._reflectionProbe) {
|
|
709
|
-
this.
|
|
709
|
+
if (!this._lightmaps?.length) // Currently reflectionprobes cant be used with lightmaps
|
|
710
|
+
this._reflectionProbe.onSet(this);
|
|
710
711
|
}
|
|
711
712
|
// since three 163 we need to set the envMap to the scene envMap if it is not set
|
|
712
713
|
// otherwise the envmapIntensity has no effect: https://github.com/mrdoob/three.js/pull/27903
|