@needle-tools/engine 4.8.7 → 4.8.8-next.4b53212
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 +13 -0
- package/README.md +55 -42
- package/components.needle.json +1 -1
- package/dist/{needle-engine.bundle-B0qaChJt.js → needle-engine.bundle-9ZWPsgka.js} +7089 -7009
- package/dist/{needle-engine.bundle-CZBThBDy.min.js → needle-engine.bundle-B-wxYHwV.min.js} +144 -144
- package/dist/{needle-engine.bundle-lBmpWgFp.umd.cjs → needle-engine.bundle-CxUl1z77.umd.cjs} +147 -147
- 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.d.ts +12 -12
- package/lib/engine/engine_addressables.js +32 -23
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_animation.d.ts +1 -3
- package/lib/engine/engine_animation.js +18 -12
- 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 +23 -3
- package/lib/engine/engine_camera.js +34 -2
- package/lib/engine/engine_camera.js.map +1 -1
- package/lib/engine/engine_context.d.ts +15 -0
- package/lib/engine/engine_context.js +33 -0
- 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/engine_loaders.callbacks.d.ts +1 -0
- package/lib/engine/engine_loaders.callbacks.js +1 -0
- package/lib/engine/engine_loaders.callbacks.js.map +1 -1
- package/lib/engine/engine_loaders.js +15 -11
- package/lib/engine/engine_loaders.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/webcomponents/needle-engine.attributes.d.ts +1 -0
- package/lib/engine/webcomponents/needle-engine.d.ts +2 -2
- package/lib/engine/webcomponents/needle-engine.js +19 -21
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine-components/Animation.js +2 -1
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/AnimationUtilsAutoplay.js +1 -6
- package/lib/engine-components/AnimationUtilsAutoplay.js.map +1 -1
- package/lib/engine-components/Camera.d.ts +2 -0
- package/lib/engine-components/Camera.js +5 -1
- package/lib/engine-components/Camera.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/DropListener.d.ts +21 -15
- package/lib/engine-components/DropListener.js +38 -34
- package/lib/engine-components/DropListener.js.map +1 -1
- package/lib/engine-components/LookAtConstraint.d.ts +5 -1
- package/lib/engine-components/LookAtConstraint.js +8 -0
- package/lib/engine-components/LookAtConstraint.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/OrbitControls.d.ts +30 -9
- package/lib/engine-components/OrbitControls.js +55 -18
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/Renderer.js +2 -1
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/Skybox.js +8 -9
- package/lib/engine-components/Skybox.js.map +1 -1
- package/lib/engine-components/api.d.ts +1 -0
- package/lib/engine-components/api.js.map +1 -1
- package/lib/engine-components/export/usdz/Extension.d.ts +1 -1
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +1 -1
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/USDZExporter.d.ts +7 -0
- package/lib/engine-components/export/usdz/USDZExporter.js +8 -1
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/engine-components/webxr/WebXRImageTracking.d.ts +4 -2
- package/lib/engine-components/webxr/WebXRImageTracking.js +117 -81
- package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
- package/package.json +3 -3
- package/plugins/common/files.js +6 -3
- package/plugins/vite/alias.js +45 -23
- package/plugins/vite/editor-connection.js +4 -4
- package/src/engine/engine_addressables.ts +46 -33
- package/src/engine/engine_animation.ts +20 -12
- package/src/engine/engine_assetdatabase.ts +7 -7
- package/src/engine/engine_camera.ts +54 -3
- package/src/engine/engine_context.ts +39 -1
- 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/engine_loaders.callbacks.ts +1 -0
- package/src/engine/engine_loaders.ts +18 -13
- 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/webcomponents/needle-engine.attributes.ts +2 -0
- package/src/engine/webcomponents/needle-engine.ts +21 -21
- package/src/engine-components/Animation.ts +1 -1
- package/src/engine-components/AnimationUtilsAutoplay.ts +1 -6
- package/src/engine-components/Camera.ts +7 -1
- package/src/engine-components/ContactShadows.ts +27 -6
- package/src/engine-components/DropListener.ts +44 -34
- package/src/engine-components/LookAtConstraint.ts +9 -1
- package/src/engine-components/NestedGltf.ts +33 -24
- package/src/engine-components/OrbitControls.ts +80 -28
- package/src/engine-components/Renderer.ts +2 -1
- package/src/engine-components/Skybox.ts +9 -10
- package/src/engine-components/api.ts +2 -1
- package/src/engine-components/export/usdz/Extension.ts +1 -1
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +1 -1
- package/src/engine-components/export/usdz/USDZExporter.ts +21 -12
- package/src/engine-components/webxr/WebXRImageTracking.ts +138 -90
|
@@ -649,12 +649,12 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
649
649
|
if (this._lookTargetLerpActive) {
|
|
650
650
|
this._lookTargetLerp01 += this.context.time.deltaTime / this._lookTargetLerpDuration;
|
|
651
651
|
if (this._lookTargetLerp01 >= 1) {
|
|
652
|
-
this.
|
|
652
|
+
this.lerpLookTarget(this._lookTargetEndPosition, this._lookTargetEndPosition, 1);
|
|
653
653
|
this._lookTargetLerpActive = false;
|
|
654
654
|
this.dispatchEvent(new CameraTargetReachedEvent(this, "lookat"));
|
|
655
655
|
} else {
|
|
656
656
|
const t = Mathf.easeInOutCubic(this._lookTargetLerp01);
|
|
657
|
-
this.
|
|
657
|
+
this.lerpLookTarget(this._lookTargetStartPosition, this._lookTargetEndPosition, t);
|
|
658
658
|
}
|
|
659
659
|
}
|
|
660
660
|
|
|
@@ -729,7 +729,9 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
729
729
|
|
|
730
730
|
// this._controls.zoomToCursor = this.zoomToCursor;
|
|
731
731
|
if (!this.context.isInXR) {
|
|
732
|
-
if (!freeCam && this.lookAtConstraint?.locked
|
|
732
|
+
if (!freeCam && this.lookAtConstraint?.locked && !this._lookTargetLerpActive) {
|
|
733
|
+
this.setLookTargetFromConstraint(0, this.lookAtConstraint01);
|
|
734
|
+
}
|
|
733
735
|
this._controls.update(this.context.time.deltaTime);
|
|
734
736
|
|
|
735
737
|
if (debug) {
|
|
@@ -887,6 +889,8 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
887
889
|
}
|
|
888
890
|
else this._fovLerpDuration = this.targetLerpDuration;
|
|
889
891
|
}
|
|
892
|
+
|
|
893
|
+
// if (this.context.mainCameraComponent) this.context.mainCameraComponent.fieldOfView = fov;
|
|
890
894
|
}
|
|
891
895
|
|
|
892
896
|
/** Moves the camera look-at target to a position smoothly.
|
|
@@ -910,7 +914,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
910
914
|
}
|
|
911
915
|
|
|
912
916
|
if (immediateOrDuration === true) {
|
|
913
|
-
this.
|
|
917
|
+
this.lerpLookTarget(this._lookTargetEndPosition, this._lookTargetEndPosition, 1);
|
|
914
918
|
}
|
|
915
919
|
else {
|
|
916
920
|
this._lookTargetLerpActive = true;
|
|
@@ -941,20 +945,18 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
941
945
|
const target = sources[index];
|
|
942
946
|
if (target) {
|
|
943
947
|
target.getWorldPosition(this._lookTargetEndPosition);
|
|
944
|
-
this.lerpLookTarget(this._lookTargetEndPosition, t);
|
|
948
|
+
this.lerpLookTarget(this._controls.target, this._lookTargetEndPosition, t);
|
|
945
949
|
return true;
|
|
946
950
|
}
|
|
947
951
|
}
|
|
948
952
|
return false;
|
|
949
953
|
}
|
|
950
954
|
|
|
951
|
-
|
|
952
|
-
public lerpTarget(position: Vector3, delta: number) { return this.lerpLookTarget(position, delta); }
|
|
953
|
-
|
|
954
|
-
private lerpLookTarget(position: Vector3, delta: number) {
|
|
955
|
+
private lerpLookTarget(start: Vector3, position: Vector3, t: number) {
|
|
955
956
|
if (!this._controls) return;
|
|
956
|
-
if (
|
|
957
|
-
else this._controls.target.
|
|
957
|
+
if (t >= 1) this._controls.target.copy(position);
|
|
958
|
+
else this._controls.target.lerpVectors(start, position, t);
|
|
959
|
+
if (this.lookAtConstraint) this.lookAtConstraint.setConstraintPosition(this._controls.target);
|
|
958
960
|
}
|
|
959
961
|
|
|
960
962
|
private setTargetFromRaycast(ray?: Ray, immediateOrDuration: number | boolean = false): boolean {
|
|
@@ -984,10 +986,11 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
984
986
|
*/
|
|
985
987
|
fitCamera(options?: FitCameraOptions);
|
|
986
988
|
fitCamera(objects?: Object3D | Array<Object3D>, options?: Omit<FitCameraOptions, "objects">);
|
|
987
|
-
fitCamera(objectsOrOptions?: Object3D | Array<Object3D> | FitCameraOptions, options?: FitCameraOptions) {
|
|
989
|
+
fitCamera(objectsOrOptions?: Object3D | Array<Object3D> | FitCameraOptions, options?: FitCameraOptions): void {
|
|
988
990
|
|
|
989
991
|
if (this.context.isInXR) {
|
|
990
992
|
// camera fitting in XR is not supported
|
|
993
|
+
console.warn('[OrbitControls] Can not fit camera while XR session is active');
|
|
991
994
|
return;
|
|
992
995
|
}
|
|
993
996
|
|
|
@@ -1032,7 +1035,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
1032
1035
|
return;
|
|
1033
1036
|
}
|
|
1034
1037
|
if (!options) options = {}
|
|
1035
|
-
const { immediate = false, centerCamera
|
|
1038
|
+
const { immediate = false, centerCamera, cameraNearFar = "auto", fitOffset = 1.1, fov = camera?.fov } = options;
|
|
1036
1039
|
const size = new Vector3();
|
|
1037
1040
|
const center = new Vector3();
|
|
1038
1041
|
// TODO would be much better to calculate the bounds in camera space instead of world space -
|
|
@@ -1041,15 +1044,13 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
1041
1044
|
// and thus we're just getting some maximum that will work for sure.
|
|
1042
1045
|
const box = getBoundingBox(objects, undefined, this._camera?.threeCamera?.layers);
|
|
1043
1046
|
const boxCopy = box.clone();
|
|
1044
|
-
|
|
1045
|
-
camera.updateMatrixWorld();
|
|
1046
|
-
camera.updateProjectionMatrix();
|
|
1047
1047
|
box.getCenter(center);
|
|
1048
1048
|
|
|
1049
1049
|
const box_size = new Vector3();
|
|
1050
1050
|
box.getSize(box_size);
|
|
1051
1051
|
|
|
1052
1052
|
// project this box into camera space
|
|
1053
|
+
camera.updateMatrixWorld();
|
|
1053
1054
|
box.applyMatrix4(camera.matrixWorldInverse);
|
|
1054
1055
|
|
|
1055
1056
|
box.getSize(size);
|
|
@@ -1063,7 +1064,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
1063
1064
|
return;
|
|
1064
1065
|
}
|
|
1065
1066
|
|
|
1066
|
-
const verticalFov =
|
|
1067
|
+
const verticalFov = fov;
|
|
1067
1068
|
const horizontalFov = 2 * Math.atan(Math.tan(verticalFov * Math.PI / 360 / 2) * camera.aspect) / Math.PI * 360;
|
|
1068
1069
|
const fitHeightDistance = size.y / (2 * Math.atan(Math.PI * verticalFov / 360));
|
|
1069
1070
|
const fitWidthDistance = size.x / (2 * Math.atan(Math.PI * horizontalFov / 360));
|
|
@@ -1078,9 +1079,18 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
1078
1079
|
this.minZoom = distance * 0.01;
|
|
1079
1080
|
|
|
1080
1081
|
const verticalOffset = 0.05;
|
|
1081
|
-
|
|
1082
1082
|
const lookAt = center.clone();
|
|
1083
1083
|
lookAt.y -= size.y * verticalOffset;
|
|
1084
|
+
if (options.targetOffset) {
|
|
1085
|
+
if (options.targetOffset.x !== undefined) lookAt.x += options.targetOffset.x;
|
|
1086
|
+
if (options.targetOffset.y !== undefined) lookAt.y += options.targetOffset.y;
|
|
1087
|
+
if (options.targetOffset.z !== undefined) lookAt.z += options.targetOffset.z;
|
|
1088
|
+
}
|
|
1089
|
+
if (options.relativeTargetOffset) {
|
|
1090
|
+
if (options.relativeTargetOffset.x !== undefined) lookAt.x += options.relativeTargetOffset.x * size.x;
|
|
1091
|
+
if (options.relativeTargetOffset.y !== undefined) lookAt.y += options.relativeTargetOffset.y * size.y;
|
|
1092
|
+
if (options.relativeTargetOffset.z !== undefined) lookAt.z += options.relativeTargetOffset.z * size.z;
|
|
1093
|
+
}
|
|
1084
1094
|
this.setLookTargetPosition(lookAt, immediate);
|
|
1085
1095
|
this.setFieldOfView(options.fov, immediate);
|
|
1086
1096
|
|
|
@@ -1092,6 +1102,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
1092
1102
|
// TODO: this doesnt take the Camera component nearClipPlane into account
|
|
1093
1103
|
camera.near = (distance / 100);
|
|
1094
1104
|
camera.far = boundsMax + distance * 10;
|
|
1105
|
+
camera.updateProjectionMatrix();
|
|
1095
1106
|
|
|
1096
1107
|
// adjust maxZoom so that the ground projection radius is always inside
|
|
1097
1108
|
if (groundprojection) {
|
|
@@ -1104,12 +1115,13 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
1104
1115
|
if (currentZoom < this.minZoom) this.minZoom = currentZoom * 0.9;
|
|
1105
1116
|
if (currentZoom > this.maxZoom) this.maxZoom = currentZoom * 1.1;
|
|
1106
1117
|
|
|
1107
|
-
camera.updateMatrixWorld();
|
|
1108
|
-
camera.updateProjectionMatrix();
|
|
1109
|
-
|
|
1110
|
-
const cameraWp = getWorldPosition(camera);
|
|
1111
1118
|
const direction = center.clone();
|
|
1112
|
-
|
|
1119
|
+
if (options.fitDirection) {
|
|
1120
|
+
direction.sub(new Vector3().copy(options.fitDirection).multiplyScalar(1_000_000));
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
direction.sub(camera.worldPosition);
|
|
1124
|
+
}
|
|
1113
1125
|
if (centerCamera === "y")
|
|
1114
1126
|
direction.y = 0;
|
|
1115
1127
|
direction.normalize();
|
|
@@ -1118,6 +1130,16 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
1118
1130
|
direction.y += -verticalOffset * 4 * distance;
|
|
1119
1131
|
|
|
1120
1132
|
let cameraLocalPosition = center.clone().sub(direction);
|
|
1133
|
+
if (options.cameraOffset) {
|
|
1134
|
+
if (options.cameraOffset.x !== undefined) cameraLocalPosition.x += options.cameraOffset.x;
|
|
1135
|
+
if (options.cameraOffset.y !== undefined) cameraLocalPosition.y += options.cameraOffset.y;
|
|
1136
|
+
if (options.cameraOffset.z !== undefined) cameraLocalPosition.z += options.cameraOffset.z;
|
|
1137
|
+
}
|
|
1138
|
+
if (options.relativeCameraOffset) {
|
|
1139
|
+
if (options.relativeCameraOffset.x !== undefined) cameraLocalPosition.x += options.relativeCameraOffset.x * size.x;
|
|
1140
|
+
if (options.relativeCameraOffset.y !== undefined) cameraLocalPosition.y += options.relativeCameraOffset.y * size.y;
|
|
1141
|
+
if (options.relativeCameraOffset.z !== undefined) cameraLocalPosition.z += options.relativeCameraOffset.z * size.z;
|
|
1142
|
+
}
|
|
1121
1143
|
if (camera.parent) {
|
|
1122
1144
|
cameraLocalPosition = camera.parent.worldToLocal(cameraLocalPosition);
|
|
1123
1145
|
}
|
|
@@ -1154,23 +1176,53 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
1154
1176
|
/**
|
|
1155
1177
|
* Options for fitting the camera to the scene. Used in {@link OrbitControls.fitCamera}
|
|
1156
1178
|
*/
|
|
1157
|
-
|
|
1179
|
+
export type FitCameraOptions = {
|
|
1158
1180
|
/** When enabled debug rendering will be shown */
|
|
1159
1181
|
debug?: boolean,
|
|
1160
1182
|
/**
|
|
1161
1183
|
* The objects to fit the camera to. If not provided the scene children will be used
|
|
1162
1184
|
*/
|
|
1163
1185
|
objects?: Object3D[] | Object3D;
|
|
1164
|
-
/** Fit offset: A factor to multiply the distance to the objects by
|
|
1165
|
-
* @default 1.1
|
|
1166
|
-
*/
|
|
1167
|
-
fitOffset?: number,
|
|
1168
1186
|
/** If true the camera will move immediately to the new position, otherwise it will lerp
|
|
1169
1187
|
* @default false
|
|
1170
1188
|
*/
|
|
1171
1189
|
immediate?: boolean,
|
|
1190
|
+
|
|
1191
|
+
/** Fit offset: A factor to multiply the distance to the objects by
|
|
1192
|
+
* @default 1.1
|
|
1193
|
+
*/
|
|
1194
|
+
fitOffset?: number,
|
|
1195
|
+
|
|
1196
|
+
/** The direction from which the camera should be fitted in worldspace. If not defined the current camera's position will be used */
|
|
1197
|
+
fitDirection?: Vector3Like,
|
|
1198
|
+
|
|
1172
1199
|
/** If set to "y" the camera will be centered in the y axis */
|
|
1173
1200
|
centerCamera?: "none" | "y",
|
|
1201
|
+
/** Set to 'auto' to update the camera near or far plane based on the fitted-objects bounds */
|
|
1174
1202
|
cameraNearFar?: "keep" | "auto",
|
|
1203
|
+
|
|
1204
|
+
/**
|
|
1205
|
+
* Offset the camera position in world space
|
|
1206
|
+
*/
|
|
1207
|
+
cameraOffset?: Partial<Vector3Like>,
|
|
1208
|
+
/**
|
|
1209
|
+
* Offset the camera position relative to the size of the objects being focused on (e.g. x: 0.5).
|
|
1210
|
+
* Value range: -1 to 1
|
|
1211
|
+
*/
|
|
1212
|
+
relativeCameraOffset?: Partial<Vector3Like>,
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Offset the camera target position in world space
|
|
1216
|
+
*/
|
|
1217
|
+
targetOffset?: Partial<Vector3Like>,
|
|
1218
|
+
/**
|
|
1219
|
+
* Offset the camera target position relative to the size of the objects being focused on.
|
|
1220
|
+
* Value range: -1 to 1
|
|
1221
|
+
*/
|
|
1222
|
+
relativeTargetOffset?: Partial<Vector3Like>,
|
|
1223
|
+
|
|
1224
|
+
/**
|
|
1225
|
+
* Field of view (FOV) for the camera
|
|
1226
|
+
*/
|
|
1175
1227
|
fov?: number,
|
|
1176
1228
|
}
|
|
@@ -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
|
|
@@ -48,21 +48,20 @@ function createRemoteSkyboxComponent(context: IContext, url: string, skybox: boo
|
|
|
48
48
|
const promises = new Array<Promise<any>>();
|
|
49
49
|
ContextRegistry.registerCallback(ContextEvent.ContextCreationStart, (args) => {
|
|
50
50
|
const context = args.context;
|
|
51
|
-
const
|
|
51
|
+
const backgroundImage = context.domElement.getAttribute("background-image");
|
|
52
52
|
const environmentImage = context.domElement.getAttribute("environment-image");
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (debug) console.log("Creating remote skybox to load " + skyboxImage);
|
|
53
|
+
|
|
54
|
+
if (backgroundImage) {
|
|
55
|
+
if (debug) console.log("Creating RemoteSkybox to load background " + backgroundImage);
|
|
57
56
|
// if the user is loading a GLB without a camera then the CameraUtils (which creates the default camera)
|
|
58
57
|
// checks if we have this attribute set and then sets the skybox clearflags accordingly
|
|
59
58
|
// if the user has a GLB with a camera but set to solid color then the skybox image is not visible -> we will just warn then and not override the camera settings
|
|
60
|
-
const promise = createRemoteSkyboxComponent(context,
|
|
59
|
+
const promise = createRemoteSkyboxComponent(context, backgroundImage, true, false, "background-image");
|
|
61
60
|
if (promise) promises.push(promise);
|
|
62
61
|
}
|
|
63
62
|
if (environmentImage) {
|
|
64
|
-
if (debug) console.log("Creating
|
|
65
|
-
const promise = createRemoteSkyboxComponent(context, environmentImage,
|
|
63
|
+
if (debug) console.log("Creating RemoteSkybox to load environment " + environmentImage);
|
|
64
|
+
const promise = createRemoteSkyboxComponent(context, environmentImage, false, true, "environment-image");
|
|
66
65
|
if (promise) promises.push(promise);
|
|
67
66
|
}
|
|
68
67
|
});
|
|
@@ -200,7 +199,7 @@ export class RemoteSkybox extends Behaviour {
|
|
|
200
199
|
console.warn("Potentially invalid skybox URL: \"" + name + "\" on " + (this.name || this.gameObject?.name || "context"));
|
|
201
200
|
}
|
|
202
201
|
|
|
203
|
-
if (debug) console.log("Set
|
|
202
|
+
if (debug) console.log("Set RemoteSkybox url: " + url);
|
|
204
203
|
|
|
205
204
|
if (this._prevUrl === url && this._prevLoadedEnvironment) {
|
|
206
205
|
this.apply();
|
|
@@ -258,7 +257,7 @@ export class RemoteSkybox extends Behaviour {
|
|
|
258
257
|
this._prevBackground = this.context.scene.background;
|
|
259
258
|
if (this.context.scene.environment !== envMap)
|
|
260
259
|
this._prevEnvironment = this.context.scene.environment;
|
|
261
|
-
if (debug) console.log("Set
|
|
260
|
+
if (debug) console.log("Set RemoteSkybox (" + ((this.environment && this.background) ? "environment and background" : this.environment ? "environment" : this.background ? "background" : "none") + ")", this.url, !Camera.backgroundShouldBeTransparent(this.context));
|
|
262
261
|
if (this.environment)
|
|
263
262
|
this.context.scene.environment = envMap;
|
|
264
263
|
if (this.background && !Camera.backgroundShouldBeTransparent(this.context))
|
|
@@ -51,8 +51,9 @@ import "./CameraUtils.js"
|
|
|
51
51
|
import "./AnimationUtils.js"
|
|
52
52
|
import "./AnimationUtilsAutoplay.js"
|
|
53
53
|
|
|
54
|
-
export { DragMode } from "./DragControls.js"
|
|
54
|
+
export { DragMode } from "./DragControls.js";
|
|
55
55
|
export type { DropListenerNetworkEventArguments, DropListenerOnDropArguments } from "./DropListener.js";
|
|
56
|
+
export { type FitCameraOptions } from "./OrbitControls.js";
|
|
56
57
|
export * from "./particlesystem/api.js"
|
|
57
58
|
|
|
58
59
|
// for correct type resolution in JSDoc
|
|
@@ -21,5 +21,5 @@ export interface IUSDExporterExtension {
|
|
|
21
21
|
onAfterBuildDocument?(context: USDZExporterContext);
|
|
22
22
|
onExportObject?(object: Object3D, model: USDObject, context: USDZExporterContext);
|
|
23
23
|
onAfterSerialize?(context: USDZExporterContext);
|
|
24
|
-
onAfterHierarchy?(context: USDZExporterContext, writer: USDWriter)
|
|
24
|
+
onAfterHierarchy?(context: USDZExporterContext, writer: USDWriter) : void | Promise<void>;
|
|
25
25
|
}
|
|
@@ -1082,7 +1082,7 @@ async function parseDocument( context: USDZExporterContext, afterStageRoot: () =
|
|
|
1082
1082
|
Progress.end("export-usdz-xforms");
|
|
1083
1083
|
|
|
1084
1084
|
Progress.report("export-usdz", "invoke onAfterHierarchy");
|
|
1085
|
-
invokeAll( context, 'onAfterHierarchy', writer );
|
|
1085
|
+
await invokeAll( context, 'onAfterHierarchy', writer );
|
|
1086
1086
|
|
|
1087
1087
|
writer.closeBlock();
|
|
1088
1088
|
writer.closeBlock();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NEEDLE_progressive } from "@needle-tools/gltf-progressive";
|
|
2
|
-
import { Euler, Matrix4, Mesh, Object3D, Quaternion, Vector3 } from "three";
|
|
2
|
+
import { Euler, EventDispatcher, Matrix4, Mesh, Object3D, Quaternion, Vector3 } from "three";
|
|
3
3
|
|
|
4
4
|
import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../../../engine/debug/index.js";
|
|
5
5
|
import { hasProLicense } from "../../../engine/engine_license.js";
|
|
@@ -12,6 +12,7 @@ import { InstancingHandler } from "../../../engine-components/RendererInstancing
|
|
|
12
12
|
import { Collider } from "../../Collider.js";
|
|
13
13
|
import { Behaviour, GameObject } from "../../Component.js";
|
|
14
14
|
import { ContactShadows } from "../../ContactShadows.js";
|
|
15
|
+
import { EventList } from "../../EventList.js";
|
|
15
16
|
import { GroundProjectedEnv } from "../../GroundProjection.js";
|
|
16
17
|
import { Renderer } from "../../Renderer.js"
|
|
17
18
|
import { Rigidbody } from "../../RigidBody.js";
|
|
@@ -71,6 +72,9 @@ export class CustomBranding {
|
|
|
71
72
|
*/
|
|
72
73
|
export class USDZExporter extends Behaviour {
|
|
73
74
|
|
|
75
|
+
static readonly beforeExport = new EventList<{ exporter: USDZExporter }>();
|
|
76
|
+
static readonly afterExport = new EventList<{ exporter: USDZExporter }>();
|
|
77
|
+
|
|
74
78
|
/**
|
|
75
79
|
* Assign the object to export as USDZ file. If undefined or null, the whole scene will be exported.
|
|
76
80
|
*/
|
|
@@ -210,7 +214,7 @@ export class USDZExporter extends Behaviour {
|
|
|
210
214
|
* Creates an USDZ file from the current scene or assigned objectToExport and opens it in QuickLook.
|
|
211
215
|
* @returns a Promise<Blob> containing the USDZ file
|
|
212
216
|
*/
|
|
213
|
-
async exportAndOpen()
|
|
217
|
+
async exportAndOpen(): Promise<Blob | null> {
|
|
214
218
|
|
|
215
219
|
let name = this.exportFileName ?? this.objectToExport?.name ?? this.name;
|
|
216
220
|
name += "-" + getFormattedDate(); // seems iOS caches the file in some cases, this ensures we always have a fresh file
|
|
@@ -221,7 +225,7 @@ export class USDZExporter extends Behaviour {
|
|
|
221
225
|
}
|
|
222
226
|
|
|
223
227
|
if (!this.link) this.link = ensureQuicklookLinkIsCreated(this.context, DeviceUtilities.supportsQuickLookAR());
|
|
224
|
-
|
|
228
|
+
|
|
225
229
|
// ability to specify a custom USDZ file to be used instead of a dynamic one
|
|
226
230
|
if (this.customUsdzFile) {
|
|
227
231
|
if (debug) console.log("Exporting custom usdz", this.customUsdzFile)
|
|
@@ -234,14 +238,19 @@ export class USDZExporter extends Behaviour {
|
|
|
234
238
|
return null;
|
|
235
239
|
}
|
|
236
240
|
|
|
237
|
-
|
|
241
|
+
USDZExporter.beforeExport.invoke({ exporter: this });
|
|
242
|
+
const blob = await this.export(this.objectToExport)
|
|
243
|
+
.finally(() => {
|
|
244
|
+
USDZExporter.afterExport.invoke({ exporter: this });
|
|
245
|
+
});
|
|
246
|
+
|
|
238
247
|
if (!blob) {
|
|
239
248
|
console.error("USDZ generation failed. Please report a bug", this);
|
|
240
249
|
return null;
|
|
241
250
|
}
|
|
242
251
|
|
|
243
252
|
if (debug) console.log("USDZ generation done. Downloading as " + name);
|
|
244
|
-
|
|
253
|
+
|
|
245
254
|
// TODO Potentially we have to detect QuickLook availability here,
|
|
246
255
|
// and download the file instead. But browsers keep changing how they deal with non-user-initiated downloads...
|
|
247
256
|
// https://webkit.org/blog/8421/viewing-augmented-reality-assets-in-safari-for-ios/#:~:text=inside%20the%20anchor.-,Feature%20Detection,-To%20detect%20support
|
|
@@ -364,7 +373,7 @@ export class USDZExporter extends Behaviour {
|
|
|
364
373
|
if (this.interactive) {
|
|
365
374
|
defaultExtensions.push(new BehaviorExtension());
|
|
366
375
|
defaultExtensions.push(new AudioExtension());
|
|
367
|
-
|
|
376
|
+
|
|
368
377
|
// If physics are enabled, and there are any Rigidbody components in the scene,
|
|
369
378
|
// add the PhysicsExtension to the default extensions.
|
|
370
379
|
if (globalThis["NEEDLE_USE_RAPIER"]) {
|
|
@@ -632,13 +641,13 @@ export class USDZExporter extends Behaviour {
|
|
|
632
641
|
private _rootPositionBeforeExport: Vector3 = new Vector3();
|
|
633
642
|
private _rootRotationBeforeExport: Quaternion = new Quaternion();
|
|
634
643
|
private _rootScaleBeforeExport: Vector3 = new Vector3();
|
|
635
|
-
|
|
636
|
-
getARScaleAndTarget(): { scale: number, _invertForward: boolean, target: Object3D, sessionRoot: Object3D | null} {
|
|
637
|
-
if (!this.objectToExport) return { scale: 1, _invertForward: false, target: this.gameObject, sessionRoot: null};
|
|
644
|
+
|
|
645
|
+
getARScaleAndTarget(): { scale: number, _invertForward: boolean, target: Object3D, sessionRoot: Object3D | null } {
|
|
646
|
+
if (!this.objectToExport) return { scale: 1, _invertForward: false, target: this.gameObject, sessionRoot: null };
|
|
638
647
|
|
|
639
648
|
const xr = GameObject.findObjectOfType(WebXR);
|
|
640
649
|
let sessionRoot = GameObject.getComponentInParent(this.objectToExport, WebARSessionRoot);
|
|
641
|
-
if(!sessionRoot) sessionRoot = GameObject.getComponentInChildren(this.objectToExport, WebARSessionRoot);
|
|
650
|
+
if (!sessionRoot) sessionRoot = GameObject.getComponentInChildren(this.objectToExport, WebARSessionRoot);
|
|
642
651
|
|
|
643
652
|
let arScale = 1;
|
|
644
653
|
let _invertForward = false;
|
|
@@ -653,7 +662,7 @@ export class USDZExporter extends Behaviour {
|
|
|
653
662
|
// eslint-disable-next-line deprecation/deprecation
|
|
654
663
|
_invertForward = sessionRoot.invertForward;
|
|
655
664
|
}
|
|
656
|
-
|
|
665
|
+
|
|
657
666
|
const scale = 1 / arScale;
|
|
658
667
|
const result = { scale, _invertForward, target, sessionRoot: sessionRoot?.gameObject ?? null };
|
|
659
668
|
return result;
|
|
@@ -699,7 +708,7 @@ export class USDZExporter extends Behaviour {
|
|
|
699
708
|
private createQuicklookButton() {
|
|
700
709
|
const buttoncontainer = WebXRButtonFactory.getOrCreate();
|
|
701
710
|
const button = buttoncontainer.createQuicklookButton();
|
|
702
|
-
if(!button.parentNode) this.context.menu.appendChild(button);
|
|
711
|
+
if (!button.parentNode) this.context.menu.appendChild(button);
|
|
703
712
|
return button;
|
|
704
713
|
}
|
|
705
714
|
}
|