@needle-tools/engine 3.5.11-beta → 3.5.13-beta
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 +9 -0
- package/dist/needle-engine.js +7719 -7687
- package/dist/needle-engine.light.js +7444 -7412
- package/dist/needle-engine.light.min.js +310 -310
- package/dist/needle-engine.light.umd.cjs +305 -305
- package/dist/needle-engine.min.js +311 -311
- package/dist/needle-engine.umd.cjs +306 -306
- package/lib/engine/debug/debug.d.ts +3 -0
- package/lib/engine/debug/debug.js +3 -0
- package/lib/engine/debug/debug.js.map +1 -1
- package/lib/engine/engine_license.js +1 -1
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_networking_instantiate.js.map +1 -1
- package/lib/engine/engine_physics_rapier.d.ts +3 -8
- package/lib/engine/engine_physics_rapier.js +30 -11
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.js +10 -9
- package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
- package/lib/engine/engine_types.d.ts +10 -3
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +6 -0
- package/lib/engine/engine_utils.js +6 -0
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine-components/CameraUtils.js +2 -1
- package/lib/engine-components/CameraUtils.js.map +1 -1
- package/lib/engine-components/OrbitControls.d.ts +1 -0
- package/lib/engine-components/OrbitControls.js +49 -13
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/Skybox.js +25 -1
- package/lib/engine-components/Skybox.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.d.ts +1 -0
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.js +1 -0
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/debug/debug.ts +3 -0
- package/src/engine/engine_license.ts +1 -1
- package/src/engine/engine_networking_instantiate.ts +1 -1
- package/src/engine/engine_physics_rapier.ts +26 -11
- package/src/engine/engine_serialization_builtin_serializer.ts +9 -9
- package/src/engine/engine_types.ts +13 -5
- package/src/engine/engine_utils.ts +6 -0
- package/src/engine-components/CameraUtils.ts +2 -1
- package/src/engine-components/OrbitControls.ts +58 -13
- package/src/engine-components/Skybox.ts +30 -6
- package/src/engine-components/export/usdz/extensions/behavior/Behaviour.ts +1 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Behaviour, GameObject } from "./Component";
|
|
2
2
|
import { Camera } from "./Camera";
|
|
3
3
|
import { LookAtConstraint } from "./LookAtConstraint";
|
|
4
|
-
import { getWorldPosition, slerp } from "../engine/engine_three_utils";
|
|
4
|
+
import { getWorldPosition, getWorldRotation, setWorldPosition, setWorldRotation, slerp } from "../engine/engine_three_utils";
|
|
5
5
|
import { RaycastOptions } from "../engine/engine_physics";
|
|
6
6
|
import { serializable } from "../engine/engine_serialization_decorator";
|
|
7
7
|
import { getParam, isMobileDevice } from "../engine/engine_utils";
|
|
8
8
|
|
|
9
|
-
import { Camera as ThreeCamera, Box3, Object3D, PerspectiveCamera, Vector2, Vector3 } from "three";
|
|
9
|
+
import { Camera as ThreeCamera, Box3, Object3D, PerspectiveCamera, Vector2, Vector3, Box3Helper } from "three";
|
|
10
10
|
import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
|
11
11
|
import { AfterHandleInputEvent, EventSystem, EventSystemEvents } from "./ui/EventSystem";
|
|
12
12
|
import { ICameraController } from "../engine/engine_types";
|
|
@@ -14,6 +14,7 @@ import { setCameraController } from "../engine/engine_camera";
|
|
|
14
14
|
import { SyncedTransform } from "./SyncedTransform";
|
|
15
15
|
|
|
16
16
|
const freeCam = getParam("freecam");
|
|
17
|
+
const debugCameraFit = getParam("debugcamerafit");
|
|
17
18
|
|
|
18
19
|
const disabledKeys = { LEFT: "", UP: "", RIGHT: "", BOTTOM: "" };
|
|
19
20
|
let defaultKeys: any = undefined;
|
|
@@ -87,7 +88,9 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
87
88
|
if (camGo && !this.setFromTargetPosition()) {
|
|
88
89
|
if (this.debugLog)
|
|
89
90
|
console.log("NO TARGET");
|
|
90
|
-
const
|
|
91
|
+
const worldPosition = getWorldPosition(camGo.cam);
|
|
92
|
+
const distanceToCenter = worldPosition.length();
|
|
93
|
+
const forward = new Vector3(0, 0, -distanceToCenter).applyMatrix4(camGo.cam.matrixWorld);
|
|
91
94
|
this.setTarget(forward, true);
|
|
92
95
|
}
|
|
93
96
|
}
|
|
@@ -349,7 +352,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
349
352
|
|
|
350
353
|
// Adapted from https://discourse.threejs.org/t/camera-zoom-to-fit-object/936/24
|
|
351
354
|
// Slower but better implementation that takes bones and exact vertex positions into account: https://github.com/google/model-viewer/blob/04e900c5027de8c5306fe1fe9627707f42811b05/packages/model-viewer/src/three-components/ModelScene.ts#L321
|
|
352
|
-
fitCameraToObjects(objects: Array<Object3D>, fitOffset: number = 1.
|
|
355
|
+
fitCameraToObjects(objects: Array<Object3D>, fitOffset: number = 1.1) {
|
|
353
356
|
const camera = this._cameraObject as PerspectiveCamera;
|
|
354
357
|
const controls = this._controls as ThreeOrbitControls | null;
|
|
355
358
|
|
|
@@ -359,20 +362,43 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
359
362
|
const center = new Vector3();
|
|
360
363
|
const box = new Box3();
|
|
361
364
|
|
|
365
|
+
// TODO would be much better to calculate the bounds in camera space instead of world space -
|
|
366
|
+
// we would get proper view-dependant fit.
|
|
367
|
+
// Right now it's independent from where the camera is actually looking from,
|
|
368
|
+
// and thus we're just getting some maximum that will work for sure.
|
|
369
|
+
|
|
362
370
|
box.makeEmpty();
|
|
363
|
-
for (const object of objects)
|
|
364
|
-
|
|
371
|
+
for (const object of objects) {
|
|
372
|
+
// ignore Box3Helpers
|
|
373
|
+
if (object instanceof Box3Helper) continue;
|
|
374
|
+
box.expandByObject(object, true);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
camera.updateMatrixWorld();
|
|
378
|
+
camera.updateProjectionMatrix();
|
|
365
379
|
|
|
366
|
-
box.getSize(size);
|
|
367
380
|
box.getCenter(center);
|
|
368
381
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
382
|
+
// project this box into camera space
|
|
383
|
+
box.applyMatrix4(camera.matrixWorldInverse);
|
|
384
|
+
|
|
385
|
+
box.getSize(size);
|
|
386
|
+
box.setFromCenterAndSize(center, size);
|
|
387
|
+
|
|
388
|
+
const verticalFov = camera.fov;
|
|
389
|
+
const horizontalFov = 2 * Math.atan(Math.tan(verticalFov * Math.PI / 360 / 2) * camera.aspect) / Math.PI * 360;
|
|
390
|
+
const fitHeightDistance = size.y / (2 * Math.atan(Math.PI * verticalFov / 360));
|
|
391
|
+
const fitWidthDistance = size.x / (2 * Math.atan(Math.PI * horizontalFov / 360));
|
|
392
|
+
|
|
393
|
+
const distance = fitOffset * Math.max(fitHeightDistance, fitWidthDistance) + size.z / 2;
|
|
373
394
|
|
|
395
|
+
if (debugCameraFit) {
|
|
396
|
+
console.log("Fit camera to objects", fitHeightDistance, fitWidthDistance, "distance", distance);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const cameraWp = getWorldPosition(camera);
|
|
374
400
|
const direction = controls.target.clone()
|
|
375
|
-
.sub(
|
|
401
|
+
.sub(cameraWp)
|
|
376
402
|
.normalize()
|
|
377
403
|
.multiplyScalar(distance);
|
|
378
404
|
|
|
@@ -382,13 +408,32 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
382
408
|
|
|
383
409
|
camera.near = distance / 100;
|
|
384
410
|
camera.far = distance * 100;
|
|
411
|
+
|
|
412
|
+
camera.updateMatrixWorld();
|
|
385
413
|
camera.updateProjectionMatrix();
|
|
386
414
|
|
|
387
|
-
camera.
|
|
415
|
+
setWorldPosition(camera, controls.target.clone().sub(direction));
|
|
416
|
+
|
|
417
|
+
if (debugCameraFit) {
|
|
418
|
+
const helper = new Box3Helper(box);
|
|
419
|
+
this.context.scene.add(helper);
|
|
420
|
+
setWorldRotation(helper, getWorldRotation(camera));
|
|
421
|
+
|
|
422
|
+
if (!this._haveAttachedKeyboardEvents) {
|
|
423
|
+
this._haveAttachedKeyboardEvents = true;
|
|
424
|
+
document.body.addEventListener("keydown", (e) => {
|
|
425
|
+
if (e.code === "KeyF") {
|
|
426
|
+
this.fitCameraToObjects(objects);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}
|
|
388
431
|
|
|
389
432
|
controls.update();
|
|
390
433
|
}
|
|
391
434
|
|
|
435
|
+
private _haveAttachedKeyboardEvents: boolean = false;
|
|
436
|
+
|
|
392
437
|
// private onPositionDrag(){
|
|
393
438
|
|
|
394
439
|
// }
|
|
@@ -5,10 +5,34 @@ import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader";
|
|
|
5
5
|
import { EquirectangularRefractionMapping, sRGBEncoding, Texture, TextureLoader } from "three"
|
|
6
6
|
import { syncField } from "../engine/engine_networking_auto";
|
|
7
7
|
import { Camera } from "./Camera";
|
|
8
|
-
import { getParam
|
|
8
|
+
import { getParam } from "../engine/engine_utils";
|
|
9
|
+
import { ContextRegistry } from "../engine/engine_context_registry";
|
|
9
10
|
|
|
10
11
|
const debug = getParam("debugskybox");
|
|
11
12
|
|
|
13
|
+
ContextRegistry.addContextCreatedCallback((args) => {
|
|
14
|
+
const context = args.context;
|
|
15
|
+
const skyboxImage = context.domElement.getAttribute("skybox-image");
|
|
16
|
+
const environmentImage = context.domElement.getAttribute("environment-image");
|
|
17
|
+
if (skyboxImage) {
|
|
18
|
+
if (debug) console.log("Creating remote skybox to load " + skyboxImage);
|
|
19
|
+
const remote = new RemoteSkybox();
|
|
20
|
+
remote.url = skyboxImage;
|
|
21
|
+
remote.allowDrop = false;
|
|
22
|
+
remote.environment = false;
|
|
23
|
+
remote.background = true;
|
|
24
|
+
GameObject.addComponent(context.scene, remote);
|
|
25
|
+
}
|
|
26
|
+
if (environmentImage) {
|
|
27
|
+
const remote = new RemoteSkybox();
|
|
28
|
+
remote.url = environmentImage;
|
|
29
|
+
remote.allowDrop = false;
|
|
30
|
+
remote.environment = true;
|
|
31
|
+
remote.background = false;
|
|
32
|
+
GameObject.addComponent(context.scene, remote);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
12
36
|
export class RemoteSkybox extends Behaviour {
|
|
13
37
|
|
|
14
38
|
@syncField("setSkybox")
|
|
@@ -53,7 +77,7 @@ export class RemoteSkybox extends Behaviour {
|
|
|
53
77
|
console.warn("Potentially invalid skybox url", this.url, "on", this.name);
|
|
54
78
|
}
|
|
55
79
|
|
|
56
|
-
if(debug) console.log("Remote skybox url?: " + url);
|
|
80
|
+
if (debug) console.log("Remote skybox url?: " + url);
|
|
57
81
|
|
|
58
82
|
if (this._prevUrl === url && this._prevLoadedEnvironment) {
|
|
59
83
|
this.applySkybox();
|
|
@@ -81,7 +105,7 @@ export class RemoteSkybox extends Behaviour {
|
|
|
81
105
|
this._loader = new TextureLoader();
|
|
82
106
|
}
|
|
83
107
|
|
|
84
|
-
if(debug) console.log("Loading skybox: " + url);
|
|
108
|
+
if (debug) console.log("Loading skybox: " + url);
|
|
85
109
|
const envMap = await this._loader.loadAsync(url);
|
|
86
110
|
if (!envMap) return;
|
|
87
111
|
// Check if we're still enabled
|
|
@@ -110,7 +134,7 @@ export class RemoteSkybox extends Behaviour {
|
|
|
110
134
|
if (this.context.scene.environment !== envMap)
|
|
111
135
|
this._prevEnvironment = this.context.scene.environment;
|
|
112
136
|
|
|
113
|
-
if(debug) console.log("Set remote skybox", this.url);
|
|
137
|
+
if (debug) console.log("Set remote skybox", this.url);
|
|
114
138
|
if (this.environment)
|
|
115
139
|
this.context.scene.environment = envMap;
|
|
116
140
|
if (this.background && !Camera.backgroundShouldBeTransparent(this.context))
|
|
@@ -147,12 +171,12 @@ export class RemoteSkybox extends Behaviour {
|
|
|
147
171
|
for (const type of e.dataTransfer.types) {
|
|
148
172
|
if (type === "text/uri-list") {
|
|
149
173
|
const url = e.dataTransfer.getData(type);
|
|
150
|
-
if(debug) console.log(type, url);
|
|
174
|
+
if (debug) console.log(type, url);
|
|
151
175
|
let name = new RegExp(/polyhaven.com\/asset_img\/.+?\/(?<name>.+)\.png/).exec(url)?.groups?.name;
|
|
152
176
|
if (!name) {
|
|
153
177
|
name = new RegExp(/polyhaven\.com\/a\/(?<name>.+)/).exec(url)?.groups?.name;
|
|
154
178
|
}
|
|
155
|
-
if(debug) console.log(name);
|
|
179
|
+
if (debug) console.log(name);
|
|
156
180
|
if (name) {
|
|
157
181
|
const envurl = "https://dl.polyhaven.org/file/ph-assets/HDRIs/exr/1k/" + name + "_1k.exr";
|
|
158
182
|
this.setSkybox(envurl);
|