@needle-tools/engine 3.5.12-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 +4 -1
- package/dist/needle-engine.js +7189 -7168
- package/dist/needle-engine.light.js +6872 -6851
- package/dist/needle-engine.light.min.js +309 -309
- package/dist/needle-engine.light.umd.cjs +304 -304
- package/dist/needle-engine.min.js +310 -310
- package/dist/needle-engine.umd.cjs +305 -305
- 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_networking_instantiate.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 +46 -12
- 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/package.json +1 -1
- package/src/engine/debug/debug.ts +3 -0
- package/src/engine/engine_networking_instantiate.ts +1 -1
- package/src/engine/engine_utils.ts +6 -0
- package/src/engine-components/CameraUtils.ts +2 -1
- package/src/engine-components/OrbitControls.ts +55 -12
- package/src/engine-components/Skybox.ts +30 -6
|
@@ -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;
|
|
@@ -351,7 +352,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
351
352
|
|
|
352
353
|
// Adapted from https://discourse.threejs.org/t/camera-zoom-to-fit-object/936/24
|
|
353
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
|
|
354
|
-
fitCameraToObjects(objects: Array<Object3D>, fitOffset: number = 1.
|
|
355
|
+
fitCameraToObjects(objects: Array<Object3D>, fitOffset: number = 1.1) {
|
|
355
356
|
const camera = this._cameraObject as PerspectiveCamera;
|
|
356
357
|
const controls = this._controls as ThreeOrbitControls | null;
|
|
357
358
|
|
|
@@ -361,20 +362,43 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
361
362
|
const center = new Vector3();
|
|
362
363
|
const box = new Box3();
|
|
363
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
|
+
|
|
364
370
|
box.makeEmpty();
|
|
365
|
-
for (const object of objects)
|
|
366
|
-
|
|
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();
|
|
367
379
|
|
|
368
|
-
box.getSize(size);
|
|
369
380
|
box.getCenter(center);
|
|
370
381
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
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;
|
|
375
394
|
|
|
395
|
+
if (debugCameraFit) {
|
|
396
|
+
console.log("Fit camera to objects", fitHeightDistance, fitWidthDistance, "distance", distance);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const cameraWp = getWorldPosition(camera);
|
|
376
400
|
const direction = controls.target.clone()
|
|
377
|
-
.sub(
|
|
401
|
+
.sub(cameraWp)
|
|
378
402
|
.normalize()
|
|
379
403
|
.multiplyScalar(distance);
|
|
380
404
|
|
|
@@ -384,13 +408,32 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
384
408
|
|
|
385
409
|
camera.near = distance / 100;
|
|
386
410
|
camera.far = distance * 100;
|
|
411
|
+
|
|
412
|
+
camera.updateMatrixWorld();
|
|
387
413
|
camera.updateProjectionMatrix();
|
|
388
414
|
|
|
389
|
-
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
|
+
}
|
|
390
431
|
|
|
391
432
|
controls.update();
|
|
392
433
|
}
|
|
393
434
|
|
|
435
|
+
private _haveAttachedKeyboardEvents: boolean = false;
|
|
436
|
+
|
|
394
437
|
// private onPositionDrag(){
|
|
395
438
|
|
|
396
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);
|