@popaya/pgsg-viewer 0.1.11 → 0.2.1
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/dist/{chunk-Z7DBLRJH.js → chunk-Q2W7KVNK.js} +5 -2
- package/dist/{chunk-Z7DBLRJH.js.map → chunk-Q2W7KVNK.js.map} +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{pgsg-three-viewer-KBOYGHT3.js → pgsg-three-viewer-B5AH6DJO.js} +183 -13
- package/dist/pgsg-three-viewer-B5AH6DJO.js.map +1 -0
- package/dist/react/index.js +188 -69
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/pgsg-three-viewer-KBOYGHT3.js.map +0 -1
|
@@ -10,7 +10,7 @@ var PGSGViewer = class {
|
|
|
10
10
|
const { PGSGPlayCanvasViewer } = await import("./pgsg-playcanvas-viewer-4WORM4WU.js");
|
|
11
11
|
this.engine = new PGSGPlayCanvasViewer(this.options);
|
|
12
12
|
} else {
|
|
13
|
-
const { PGSGThreeViewer } = await import("./pgsg-three-viewer-
|
|
13
|
+
const { PGSGThreeViewer } = await import("./pgsg-three-viewer-B5AH6DJO.js");
|
|
14
14
|
this.engine = new PGSGThreeViewer(this.options);
|
|
15
15
|
}
|
|
16
16
|
await this.engine.load();
|
|
@@ -37,9 +37,12 @@ var PGSGViewer = class {
|
|
|
37
37
|
enablePlacementMode(url) {
|
|
38
38
|
return this.engine?.enablePlacementMode?.(url);
|
|
39
39
|
}
|
|
40
|
+
enableInput(enabled) {
|
|
41
|
+
return this.engine?.enableInput?.(enabled);
|
|
42
|
+
}
|
|
40
43
|
};
|
|
41
44
|
|
|
42
45
|
export {
|
|
43
46
|
PGSGViewer
|
|
44
47
|
};
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
48
|
+
//# sourceMappingURL=chunk-Q2W7KVNK.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/viewer/pgsg-viewer.ts"],"sourcesContent":["import * as THREE from \"three\";\n\nimport type {\n ViewerType,\n PGSGViewerEngine,\n CameraMode,\n} from \"../viewers/types\";\nimport type { PGSGViewerOptions } from \"../core/types\";\n\nexport class PGSGViewer {\n private engine!: PGSGViewerEngine;\n\n constructor(\n private options: PGSGViewerOptions & { viewerType?: ViewerType },\n ) {}\n\n async load() {\n const type = this.options.viewerType ?? \"three\";\n\n if (type === \"playcanvas\") {\n const { PGSGPlayCanvasViewer } =\n await import(\"../viewers/playcanvas/pgsg-playcanvas-viewer\");\n this.engine = new PGSGPlayCanvasViewer(this.options);\n } else {\n const { PGSGThreeViewer } =\n await import(\"../viewers/three/pgsg-three-viewer\");\n this.engine = new PGSGThreeViewer(this.options);\n }\n\n await this.engine.load();\n this.engine.start?.();\n }\n\n resize() {\n this.engine?.resize();\n }\n\n destroy() {\n this.engine?.destroy();\n }\n\n setCameraMode(mode: CameraMode) {\n this.engine?.setCameraMode?.(mode);\n }\n\n finalizePolyline() {\n (this.engine as any)?.finalizePolyline?.();\n }\n\n deleteMeasurement(index: number) {\n (this.engine as any)?.deleteMeasurement?.(index);\n }\n\n async addModelFromUrl(url: string, position?: THREE.Vector3) {\n return this.engine?.addModelFromUrl?.(url, position);\n }\n\n enablePlacementMode(url: string) {\n return this.engine?.enablePlacementMode?.(url);\n }\n}\n"],"mappings":";AASO,IAAM,aAAN,MAAiB;AAAA,EAGtB,YACU,SACR;AADQ;AAAA,EACP;AAAA,EAJK;AAAA,EAMR,MAAM,OAAO;AACX,UAAM,OAAO,KAAK,QAAQ,cAAc;AAExC,QAAI,SAAS,cAAc;AACzB,YAAM,EAAE,qBAAqB,IAC3B,MAAM,OAAO,sCAA8C;AAC7D,WAAK,SAAS,IAAI,qBAAqB,KAAK,OAAO;AAAA,IACrD,OAAO;AACL,YAAM,EAAE,gBAAgB,IACtB,MAAM,OAAO,iCAAoC;AACnD,WAAK,SAAS,IAAI,gBAAgB,KAAK,OAAO;AAAA,IAChD;AAEA,UAAM,KAAK,OAAO,KAAK;AACvB,SAAK,OAAO,QAAQ;AAAA,EACtB;AAAA,EAEA,SAAS;AACP,SAAK,QAAQ,OAAO;AAAA,EACtB;AAAA,EAEA,UAAU;AACR,SAAK,QAAQ,QAAQ;AAAA,EACvB;AAAA,EAEA,cAAc,MAAkB;AAC9B,SAAK,QAAQ,gBAAgB,IAAI;AAAA,EACnC;AAAA,EAEA,mBAAmB;AACjB,IAAC,KAAK,QAAgB,mBAAmB;AAAA,EAC3C;AAAA,EAEA,kBAAkB,OAAe;AAC/B,IAAC,KAAK,QAAgB,oBAAoB,KAAK;AAAA,EACjD;AAAA,EAEA,MAAM,gBAAgB,KAAa,UAA0B;AAC3D,WAAO,KAAK,QAAQ,kBAAkB,KAAK,QAAQ;AAAA,EACrD;AAAA,EAEA,oBAAoB,KAAa;AAC/B,WAAO,KAAK,QAAQ,sBAAsB,GAAG;AAAA,EAC/C;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/viewer/pgsg-viewer.ts"],"sourcesContent":["import * as THREE from \"three\";\n\nimport type {\n ViewerType,\n PGSGViewerEngine,\n CameraMode,\n} from \"../viewers/types\";\nimport type { PGSGViewerOptions } from \"../core/types\";\n\nexport class PGSGViewer {\n private engine!: PGSGViewerEngine;\n\n constructor(\n private options: PGSGViewerOptions & { viewerType?: ViewerType },\n ) {}\n\n async load() {\n const type = this.options.viewerType ?? \"three\";\n\n if (type === \"playcanvas\") {\n const { PGSGPlayCanvasViewer } =\n await import(\"../viewers/playcanvas/pgsg-playcanvas-viewer\");\n this.engine = new PGSGPlayCanvasViewer(this.options);\n } else {\n const { PGSGThreeViewer } =\n await import(\"../viewers/three/pgsg-three-viewer\");\n this.engine = new PGSGThreeViewer(this.options);\n }\n\n await this.engine.load();\n this.engine.start?.();\n }\n\n resize() {\n this.engine?.resize();\n }\n\n destroy() {\n this.engine?.destroy();\n }\n\n setCameraMode(mode: CameraMode) {\n this.engine?.setCameraMode?.(mode);\n }\n\n finalizePolyline() {\n (this.engine as any)?.finalizePolyline?.();\n }\n\n deleteMeasurement(index: number) {\n (this.engine as any)?.deleteMeasurement?.(index);\n }\n\n async addModelFromUrl(url: string, position?: THREE.Vector3) {\n return this.engine?.addModelFromUrl?.(url, position);\n }\n\n enablePlacementMode(url: string) {\n return this.engine?.enablePlacementMode?.(url);\n }\n\n enableInput(enabled: boolean) {\n return this.engine?.enableInput?.(enabled);\n }\n}\n"],"mappings":";AASO,IAAM,aAAN,MAAiB;AAAA,EAGtB,YACU,SACR;AADQ;AAAA,EACP;AAAA,EAJK;AAAA,EAMR,MAAM,OAAO;AACX,UAAM,OAAO,KAAK,QAAQ,cAAc;AAExC,QAAI,SAAS,cAAc;AACzB,YAAM,EAAE,qBAAqB,IAC3B,MAAM,OAAO,sCAA8C;AAC7D,WAAK,SAAS,IAAI,qBAAqB,KAAK,OAAO;AAAA,IACrD,OAAO;AACL,YAAM,EAAE,gBAAgB,IACtB,MAAM,OAAO,iCAAoC;AACnD,WAAK,SAAS,IAAI,gBAAgB,KAAK,OAAO;AAAA,IAChD;AAEA,UAAM,KAAK,OAAO,KAAK;AACvB,SAAK,OAAO,QAAQ;AAAA,EACtB;AAAA,EAEA,SAAS;AACP,SAAK,QAAQ,OAAO;AAAA,EACtB;AAAA,EAEA,UAAU;AACR,SAAK,QAAQ,QAAQ;AAAA,EACvB;AAAA,EAEA,cAAc,MAAkB;AAC9B,SAAK,QAAQ,gBAAgB,IAAI;AAAA,EACnC;AAAA,EAEA,mBAAmB;AACjB,IAAC,KAAK,QAAgB,mBAAmB;AAAA,EAC3C;AAAA,EAEA,kBAAkB,OAAe;AAC/B,IAAC,KAAK,QAAgB,oBAAoB,KAAK;AAAA,EACjD;AAAA,EAEA,MAAM,gBAAgB,KAAa,UAA0B;AAC3D,WAAO,KAAK,QAAQ,kBAAkB,KAAK,QAAQ;AAAA,EACrD;AAAA,EAEA,oBAAoB,KAAa;AAC/B,WAAO,KAAK,QAAQ,sBAAsB,GAAG;AAAA,EAC/C;AAAA,EAEA,YAAY,SAAkB;AAC5B,WAAO,KAAK,QAAQ,cAAc,OAAO;AAAA,EAC3C;AACF;","names":[]}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ declare class PGSGViewer {
|
|
|
51
51
|
deleteMeasurement(index: number): void;
|
|
52
52
|
addModelFromUrl(url: string, position?: THREE.Vector3): Promise<THREE.Object3D<THREE.Object3DEventMap> | null | undefined>;
|
|
53
53
|
enablePlacementMode(url: string): void | undefined;
|
|
54
|
+
enableInput(enabled: boolean): void | undefined;
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
export { type CameraOptions, type ControlOptions, type PGSGSource, PGSGViewer, type PGSGViewerOptions, type PLYSource, type SourceType, type ViewerSource };
|
package/dist/core/index.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// src/viewers/three/pgsg-three-viewer.ts
|
|
2
2
|
import * as THREE5 from "three";
|
|
3
|
-
import { GLTFLoader } from "three/
|
|
4
|
-
import { TransformControls } from "three/
|
|
3
|
+
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
4
|
+
import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
|
|
5
|
+
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
|
|
6
|
+
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
|
|
7
|
+
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js";
|
|
8
|
+
import { OutputPass } from "three/examples/jsm/postprocessing/OutputPass.js";
|
|
5
9
|
import * as RAPIER2 from "@dimforge/rapier3d-compat";
|
|
6
10
|
import nipplejs from "nipplejs";
|
|
7
11
|
|
|
@@ -294,6 +298,7 @@ var OrbitCameraController = class {
|
|
|
294
298
|
lastTouchY = 0;
|
|
295
299
|
externalMove = new THREE2.Vector2(0, 0);
|
|
296
300
|
moveSpeed = 5;
|
|
301
|
+
enabled = true;
|
|
297
302
|
constructor(camera, dom, opts) {
|
|
298
303
|
this.camera = camera;
|
|
299
304
|
this.dom = dom;
|
|
@@ -371,6 +376,7 @@ var OrbitCameraController = class {
|
|
|
371
376
|
// Input
|
|
372
377
|
// -----------------------------
|
|
373
378
|
onMouseDown = (e) => {
|
|
379
|
+
if (!this.enabled) return;
|
|
374
380
|
if (e.button === 0) {
|
|
375
381
|
this.dragging = true;
|
|
376
382
|
} else if (e.button === 2 || e.button === 1) {
|
|
@@ -384,6 +390,7 @@ var OrbitCameraController = class {
|
|
|
384
390
|
this.panning = false;
|
|
385
391
|
};
|
|
386
392
|
onMouseMove = (e) => {
|
|
393
|
+
if (!this.enabled) return;
|
|
387
394
|
if (!this.dragging && !this.panning) return;
|
|
388
395
|
const dx = e.clientX - this.lastX;
|
|
389
396
|
const dy = e.clientY - this.lastY;
|
|
@@ -412,6 +419,7 @@ var OrbitCameraController = class {
|
|
|
412
419
|
}
|
|
413
420
|
};
|
|
414
421
|
onWheel = (e) => {
|
|
422
|
+
if (!this.enabled) return;
|
|
415
423
|
e.preventDefault();
|
|
416
424
|
const zoomFactor = Math.pow(this.zoomSpeed, e.deltaY / 100);
|
|
417
425
|
this.distance *= zoomFactor;
|
|
@@ -423,11 +431,13 @@ var OrbitCameraController = class {
|
|
|
423
431
|
this.updateCamera();
|
|
424
432
|
};
|
|
425
433
|
onTouchStart = (e) => {
|
|
434
|
+
if (!this.enabled) return;
|
|
426
435
|
const t = e.touches[0];
|
|
427
436
|
this.lastTouchX = t.clientX;
|
|
428
437
|
this.lastTouchY = t.clientY;
|
|
429
438
|
};
|
|
430
439
|
onTouchMove = (e) => {
|
|
440
|
+
if (!this.enabled) return;
|
|
431
441
|
const t = e.touches[0];
|
|
432
442
|
const deltaX = t.clientX - this.lastTouchX;
|
|
433
443
|
const deltaY = t.clientY - this.lastTouchY;
|
|
@@ -1005,6 +1015,15 @@ var PGSGThreeViewer = class {
|
|
|
1005
1015
|
mouse = new THREE5.Vector2();
|
|
1006
1016
|
placementRotation = 0;
|
|
1007
1017
|
transformControls;
|
|
1018
|
+
inputEnabled = true;
|
|
1019
|
+
placementMouseMoved = false;
|
|
1020
|
+
placedObjects = [];
|
|
1021
|
+
ghostYOffset = 0;
|
|
1022
|
+
composer;
|
|
1023
|
+
hoverOutline;
|
|
1024
|
+
selectOutline;
|
|
1025
|
+
selectedObject;
|
|
1026
|
+
hoveredObject;
|
|
1008
1027
|
container;
|
|
1009
1028
|
resizeObserver = null;
|
|
1010
1029
|
controls;
|
|
@@ -1031,21 +1050,28 @@ var PGSGThreeViewer = class {
|
|
|
1031
1050
|
this.initRenderer();
|
|
1032
1051
|
this.initCamera();
|
|
1033
1052
|
this.initScene();
|
|
1053
|
+
this.initPostProcessing();
|
|
1034
1054
|
this.bindResize();
|
|
1035
1055
|
this.resize();
|
|
1036
1056
|
this.transformControls = new TransformControls(
|
|
1037
1057
|
this.camera,
|
|
1038
1058
|
this.renderer.domElement
|
|
1039
1059
|
);
|
|
1040
|
-
this.scene.add(this.transformControls);
|
|
1041
|
-
console.log(this.transformControls instanceof THREE5.Object3D);
|
|
1060
|
+
this.scene.add(this.transformControls.getHelper());
|
|
1061
|
+
console.log(this.transformControls.getHelper() instanceof THREE5.Object3D);
|
|
1042
1062
|
this.transformControls.addEventListener("dragging-changed", (event) => {
|
|
1043
1063
|
if (!this.controls) return;
|
|
1044
1064
|
this.controls.enabled = !event.value;
|
|
1045
1065
|
});
|
|
1046
1066
|
this.transformControls.addEventListener("mouseDown", () => {
|
|
1047
1067
|
document.exitPointerLock?.();
|
|
1068
|
+
this.controls.enabled = false;
|
|
1048
1069
|
});
|
|
1070
|
+
this.transformControls.addEventListener("mouseUp", () => {
|
|
1071
|
+
this.controls.enabled = true;
|
|
1072
|
+
});
|
|
1073
|
+
this.transformControls.setSize(0.8);
|
|
1074
|
+
this.transformControls.setSpace("world");
|
|
1049
1075
|
await RAPIER2.init();
|
|
1050
1076
|
this.world = new RAPIER2.World({
|
|
1051
1077
|
x: 0,
|
|
@@ -1073,12 +1099,26 @@ var PGSGThreeViewer = class {
|
|
|
1073
1099
|
}
|
|
1074
1100
|
window.addEventListener("keydown", this.onKeyToggle);
|
|
1075
1101
|
window.addEventListener("keydown", (e) => {
|
|
1102
|
+
if (!this.inputEnabled) return;
|
|
1076
1103
|
if (!this.transformControls) return;
|
|
1077
1104
|
if (e.key === "r") this.transformControls.setMode("rotate");
|
|
1078
1105
|
if (e.key === "t") this.transformControls.setMode("translate");
|
|
1079
1106
|
if (e.key === "s") this.transformControls.setMode("scale");
|
|
1080
1107
|
});
|
|
1081
|
-
this.renderer.domElement.addEventListener("
|
|
1108
|
+
this.renderer.domElement.addEventListener("mousedown", () => {
|
|
1109
|
+
this.placementMouseMoved = false;
|
|
1110
|
+
});
|
|
1111
|
+
this.renderer.domElement.addEventListener("mousemove", () => {
|
|
1112
|
+
this.placementMouseMoved = true;
|
|
1113
|
+
});
|
|
1114
|
+
this.renderer.domElement.addEventListener("mouseup", (e) => {
|
|
1115
|
+
if (!this.placementMouseMoved) {
|
|
1116
|
+
this.onSceneClick(e);
|
|
1117
|
+
}
|
|
1118
|
+
});
|
|
1119
|
+
this.renderer.domElement.addEventListener("click", this.onSelectObject);
|
|
1120
|
+
this.renderer.domElement.addEventListener("mousemove", this.onHoverObject);
|
|
1121
|
+
window.addEventListener("keydown", this.onDeleteObject);
|
|
1082
1122
|
}
|
|
1083
1123
|
start() {
|
|
1084
1124
|
if (this.running) return;
|
|
@@ -1094,7 +1134,7 @@ var PGSGThreeViewer = class {
|
|
|
1094
1134
|
this.acc -= this.fixedDt;
|
|
1095
1135
|
}
|
|
1096
1136
|
this.controls?.update?.(delta);
|
|
1097
|
-
this.
|
|
1137
|
+
this.composer.render();
|
|
1098
1138
|
});
|
|
1099
1139
|
}
|
|
1100
1140
|
pause() {
|
|
@@ -1105,6 +1145,9 @@ var PGSGThreeViewer = class {
|
|
|
1105
1145
|
const w = Math.max(1, this.container.clientWidth);
|
|
1106
1146
|
const h = Math.max(1, this.container.clientHeight);
|
|
1107
1147
|
this.renderer.setSize(w, h);
|
|
1148
|
+
this.composer?.setSize(w, h);
|
|
1149
|
+
this.hoverOutline?.setSize(w, h);
|
|
1150
|
+
this.selectOutline?.setSize(w, h);
|
|
1108
1151
|
this.camera.aspect = w / h;
|
|
1109
1152
|
this.camera.updateProjectionMatrix();
|
|
1110
1153
|
}
|
|
@@ -1166,6 +1209,7 @@ var PGSGThreeViewer = class {
|
|
|
1166
1209
|
this.pendingPlacementUrl = url;
|
|
1167
1210
|
this.placementRotation = 0;
|
|
1168
1211
|
console.log("[PGSG Viewer] Placement mode enabled");
|
|
1212
|
+
this.controls.enabled = false;
|
|
1169
1213
|
const gltf = await this.gltfLoader.loadAsync(url);
|
|
1170
1214
|
this.ghostModel = gltf.scene;
|
|
1171
1215
|
const box = new THREE5.Box3().setFromObject(this.ghostModel);
|
|
@@ -1186,8 +1230,17 @@ var PGSGThreeViewer = class {
|
|
|
1186
1230
|
this.onPlacementMove
|
|
1187
1231
|
);
|
|
1188
1232
|
this.renderer.domElement.addEventListener("wheel", this.onPlacementWheel);
|
|
1189
|
-
this.renderer.domElement.addEventListener("click", this.onSceneClick);
|
|
1190
1233
|
window.addEventListener("keydown", this.onPlacementCancel);
|
|
1234
|
+
const rect = this.renderer.domElement.getBoundingClientRect();
|
|
1235
|
+
this.mouse.set(0, 0);
|
|
1236
|
+
this.raycaster.setFromCamera(this.mouse, this.camera);
|
|
1237
|
+
const intersects = this.raycaster.intersectObjects(
|
|
1238
|
+
this.colliderMeshes,
|
|
1239
|
+
true
|
|
1240
|
+
);
|
|
1241
|
+
if (intersects.length) {
|
|
1242
|
+
this.ghostModel.position.copy(intersects[0].point);
|
|
1243
|
+
}
|
|
1191
1244
|
}
|
|
1192
1245
|
async addModelFromUrl(url, position) {
|
|
1193
1246
|
return new Promise((resolve, reject) => {
|
|
@@ -1214,6 +1267,9 @@ var PGSGThreeViewer = class {
|
|
|
1214
1267
|
);
|
|
1215
1268
|
});
|
|
1216
1269
|
}
|
|
1270
|
+
enableInput(enabled) {
|
|
1271
|
+
this.inputEnabled = enabled;
|
|
1272
|
+
}
|
|
1217
1273
|
// ---------------------------
|
|
1218
1274
|
// Init
|
|
1219
1275
|
// ---------------------------
|
|
@@ -1233,14 +1289,21 @@ var PGSGThreeViewer = class {
|
|
|
1233
1289
|
this.renderer.setPixelRatio(
|
|
1234
1290
|
this.options.renderer?.pixelRatio ?? window.devicePixelRatio
|
|
1235
1291
|
);
|
|
1292
|
+
this.renderer.toneMapping = THREE5.ACESFilmicToneMapping;
|
|
1293
|
+
this.renderer.toneMappingExposure = 1.2;
|
|
1236
1294
|
this.renderer.localClippingEnabled = true;
|
|
1237
1295
|
this.container.appendChild(this.renderer.domElement);
|
|
1238
1296
|
}
|
|
1239
1297
|
initScene() {
|
|
1240
1298
|
this.scene = new THREE5.Scene();
|
|
1241
1299
|
this.scene.background = new THREE5.Color(1118481);
|
|
1242
|
-
const
|
|
1243
|
-
this.scene.add(
|
|
1300
|
+
const hemi = new THREE5.HemisphereLight(16777215, 4473924, 1.2);
|
|
1301
|
+
this.scene.add(hemi);
|
|
1302
|
+
const dir = new THREE5.DirectionalLight(16777215, 2.5);
|
|
1303
|
+
dir.position.set(5, 10, 5);
|
|
1304
|
+
this.scene.add(dir);
|
|
1305
|
+
const amb = new THREE5.AmbientLight(16777215, 0.35);
|
|
1306
|
+
this.scene.add(amb);
|
|
1244
1307
|
}
|
|
1245
1308
|
initCamera() {
|
|
1246
1309
|
this.camera = new THREE5.PerspectiveCamera(
|
|
@@ -1252,6 +1315,31 @@ var PGSGThreeViewer = class {
|
|
|
1252
1315
|
this.camera.position.set(2, 2, 5);
|
|
1253
1316
|
this.camera.lookAt(0, 0, 0);
|
|
1254
1317
|
}
|
|
1318
|
+
initPostProcessing() {
|
|
1319
|
+
this.composer = new EffectComposer(this.renderer);
|
|
1320
|
+
this.composer.addPass(new RenderPass(this.scene, this.camera));
|
|
1321
|
+
const size = new THREE5.Vector2(
|
|
1322
|
+
this.container.clientWidth,
|
|
1323
|
+
this.container.clientHeight
|
|
1324
|
+
);
|
|
1325
|
+
this.hoverOutline = new OutlinePass(size, this.scene, this.camera);
|
|
1326
|
+
this.hoverOutline.edgeStrength = 6;
|
|
1327
|
+
this.hoverOutline.edgeGlow = 1;
|
|
1328
|
+
this.hoverOutline.edgeThickness = 2;
|
|
1329
|
+
this.hoverOutline.pulsePeriod = 0;
|
|
1330
|
+
this.hoverOutline.visibleEdgeColor.set("#00e5ff");
|
|
1331
|
+
this.hoverOutline.hiddenEdgeColor.set("#00e5ff");
|
|
1332
|
+
this.composer.addPass(this.hoverOutline);
|
|
1333
|
+
this.selectOutline = new OutlinePass(size, this.scene, this.camera);
|
|
1334
|
+
this.selectOutline.edgeStrength = 8;
|
|
1335
|
+
this.selectOutline.edgeGlow = 1.2;
|
|
1336
|
+
this.selectOutline.edgeThickness = 2.5;
|
|
1337
|
+
this.selectOutline.pulsePeriod = 0;
|
|
1338
|
+
this.selectOutline.visibleEdgeColor.set("#ffd400");
|
|
1339
|
+
this.selectOutline.hiddenEdgeColor.set("#ffd400");
|
|
1340
|
+
this.composer.addPass(this.selectOutline);
|
|
1341
|
+
this.composer.addPass(new OutputPass());
|
|
1342
|
+
}
|
|
1255
1343
|
bindResize() {
|
|
1256
1344
|
this.resizeObserver?.disconnect();
|
|
1257
1345
|
this.resizeObserver = new ResizeObserver(() => this.resize());
|
|
@@ -1293,6 +1381,7 @@ var PGSGThreeViewer = class {
|
|
|
1293
1381
|
cd.setFriction(0.9);
|
|
1294
1382
|
cd.setRestitution(0);
|
|
1295
1383
|
this.world.createCollider(cd, rb);
|
|
1384
|
+
child.visible = false;
|
|
1296
1385
|
this.colliderMeshes.push(child);
|
|
1297
1386
|
});
|
|
1298
1387
|
const rawBox = new THREE5.Box3().setFromObject(colliderRoot);
|
|
@@ -1303,6 +1392,7 @@ var PGSGThreeViewer = class {
|
|
|
1303
1392
|
// Mode switching
|
|
1304
1393
|
// ---------------------------
|
|
1305
1394
|
onKeyToggle = (e) => {
|
|
1395
|
+
if (!this.inputEnabled) return;
|
|
1306
1396
|
if (e.key !== "v") return;
|
|
1307
1397
|
if (this.controls instanceof RapierWalkController) this.switchToOrbit();
|
|
1308
1398
|
else this.switchToWalk();
|
|
@@ -1482,16 +1572,21 @@ var PGSGThreeViewer = class {
|
|
|
1482
1572
|
return hits;
|
|
1483
1573
|
}
|
|
1484
1574
|
onSceneClick = async (event) => {
|
|
1575
|
+
if (this.placementMouseMoved) return;
|
|
1485
1576
|
if (!this.pendingPlacementUrl || !this.ghostModel) return;
|
|
1486
1577
|
const position = this.ghostModel.position.clone();
|
|
1487
1578
|
const placed = await this.addModelFromUrl(
|
|
1488
1579
|
this.pendingPlacementUrl,
|
|
1489
1580
|
position
|
|
1490
1581
|
);
|
|
1582
|
+
if (placed) {
|
|
1583
|
+
this.placedObjects.push(placed);
|
|
1584
|
+
}
|
|
1491
1585
|
if (placed && this.transformControls) {
|
|
1492
1586
|
placed.rotation.y = this.placementRotation;
|
|
1493
1587
|
this.transformControls.attach(placed);
|
|
1494
1588
|
}
|
|
1589
|
+
this.controls.enabled = true;
|
|
1495
1590
|
this.scene.remove(this.ghostModel);
|
|
1496
1591
|
this.ghostModel = void 0;
|
|
1497
1592
|
this.pendingPlacementUrl = void 0;
|
|
@@ -1503,7 +1598,6 @@ var PGSGThreeViewer = class {
|
|
|
1503
1598
|
"wheel",
|
|
1504
1599
|
this.onPlacementWheel
|
|
1505
1600
|
);
|
|
1506
|
-
this.renderer.domElement.removeEventListener("click", this.onSceneClick);
|
|
1507
1601
|
window.removeEventListener("keydown", this.onPlacementCancel);
|
|
1508
1602
|
};
|
|
1509
1603
|
onPlacementMove = (event) => {
|
|
@@ -1519,10 +1613,23 @@ var PGSGThreeViewer = class {
|
|
|
1519
1613
|
true
|
|
1520
1614
|
);
|
|
1521
1615
|
if (!intersects.length) return;
|
|
1522
|
-
const
|
|
1523
|
-
this.ghostModel
|
|
1616
|
+
const hit = intersects[0];
|
|
1617
|
+
const box = new THREE5.Box3().setFromObject(this.ghostModel);
|
|
1618
|
+
this.ghostYOffset = -box.min.y;
|
|
1619
|
+
this.ghostModel.position.copy(hit.point);
|
|
1620
|
+
this.ghostModel.position.y += this.ghostYOffset;
|
|
1621
|
+
if (hit.face) {
|
|
1622
|
+
const normal = this.getWorldNormalSafe(hit);
|
|
1623
|
+
if (normal) {
|
|
1624
|
+
const up = new THREE5.Vector3(0, 1, 0);
|
|
1625
|
+
const quat = new THREE5.Quaternion().setFromUnitVectors(up, normal);
|
|
1626
|
+
this.ghostModel.quaternion.copy(quat);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1524
1629
|
};
|
|
1525
1630
|
onPlacementWheel = (event) => {
|
|
1631
|
+
event.preventDefault();
|
|
1632
|
+
event.stopPropagation();
|
|
1526
1633
|
if (!this.ghostModel) return;
|
|
1527
1634
|
event.preventDefault();
|
|
1528
1635
|
const step = Math.PI / 12;
|
|
@@ -1552,8 +1659,71 @@ var PGSGThreeViewer = class {
|
|
|
1552
1659
|
);
|
|
1553
1660
|
window.removeEventListener("keydown", this.onPlacementCancel);
|
|
1554
1661
|
};
|
|
1662
|
+
onSelectObject = (event) => {
|
|
1663
|
+
if (this.pendingPlacementUrl) return;
|
|
1664
|
+
if (this.transformControls?.dragging) return;
|
|
1665
|
+
const rect = this.renderer.domElement.getBoundingClientRect();
|
|
1666
|
+
this.mouse.set(
|
|
1667
|
+
(event.clientX - rect.left) / rect.width * 2 - 1,
|
|
1668
|
+
-((event.clientY - rect.top) / rect.height) * 2 + 1
|
|
1669
|
+
);
|
|
1670
|
+
this.raycaster.setFromCamera(this.mouse, this.camera);
|
|
1671
|
+
const hits = this.raycaster.intersectObjects(this.placedObjects, true);
|
|
1672
|
+
if (!hits.length) {
|
|
1673
|
+
this.selectedObject = void 0;
|
|
1674
|
+
this.transformControls?.detach();
|
|
1675
|
+
this.selectOutline.selectedObjects = [];
|
|
1676
|
+
return;
|
|
1677
|
+
}
|
|
1678
|
+
let root = hits[0].object;
|
|
1679
|
+
while (root && !this.placedObjects.includes(root)) root = root.parent;
|
|
1680
|
+
if (!root) return;
|
|
1681
|
+
this.selectedObject = root;
|
|
1682
|
+
this.transformControls?.attach(root);
|
|
1683
|
+
this.selectOutline.selectedObjects = [root];
|
|
1684
|
+
};
|
|
1685
|
+
onHoverObject = (event) => {
|
|
1686
|
+
if (this.pendingPlacementUrl) return;
|
|
1687
|
+
if (this.transformControls?.dragging) return;
|
|
1688
|
+
const rect = this.renderer.domElement.getBoundingClientRect();
|
|
1689
|
+
this.mouse.set(
|
|
1690
|
+
(event.clientX - rect.left) / rect.width * 2 - 1,
|
|
1691
|
+
-((event.clientY - rect.top) / rect.height) * 2 + 1
|
|
1692
|
+
);
|
|
1693
|
+
this.raycaster.setFromCamera(this.mouse, this.camera);
|
|
1694
|
+
const hits = this.raycaster.intersectObjects(this.placedObjects, true);
|
|
1695
|
+
if (!hits.length) {
|
|
1696
|
+
this.hoveredObject = void 0;
|
|
1697
|
+
this.hoverOutline.selectedObjects = [];
|
|
1698
|
+
this.renderer.domElement.style.cursor = "default";
|
|
1699
|
+
return;
|
|
1700
|
+
}
|
|
1701
|
+
let root = hits[0].object;
|
|
1702
|
+
while (root && !this.placedObjects.includes(root)) root = root.parent;
|
|
1703
|
+
if (!root) return;
|
|
1704
|
+
if (root !== this.hoveredObject) {
|
|
1705
|
+
this.hoveredObject = root;
|
|
1706
|
+
this.hoverOutline.selectedObjects = [root];
|
|
1707
|
+
this.renderer.domElement.style.cursor = "pointer";
|
|
1708
|
+
}
|
|
1709
|
+
};
|
|
1710
|
+
onDeleteObject = (event) => {
|
|
1711
|
+
const tag = event.target?.tagName?.toLowerCase();
|
|
1712
|
+
if (tag === "input" || tag === "textarea") return;
|
|
1713
|
+
if (event.key !== "Delete" && event.key !== "Backspace") return;
|
|
1714
|
+
if (!this.selectedObject) return;
|
|
1715
|
+
event.preventDefault();
|
|
1716
|
+
this.selectedObject.parent?.remove(this.selectedObject);
|
|
1717
|
+
this.placedObjects = this.placedObjects.filter(
|
|
1718
|
+
(o) => o !== this.selectedObject
|
|
1719
|
+
);
|
|
1720
|
+
this.transformControls?.detach();
|
|
1721
|
+
this.selectOutline.selectedObjects = [];
|
|
1722
|
+
this.hoverOutline.selectedObjects = [];
|
|
1723
|
+
this.selectedObject = void 0;
|
|
1724
|
+
};
|
|
1555
1725
|
};
|
|
1556
1726
|
export {
|
|
1557
1727
|
PGSGThreeViewer
|
|
1558
1728
|
};
|
|
1559
|
-
//# sourceMappingURL=pgsg-three-viewer-
|
|
1729
|
+
//# sourceMappingURL=pgsg-three-viewer-B5AH6DJO.js.map
|