|
|
@@ -0,0 +1,108 @@
|
|
|
+import * as THREE from 'three';
|
|
|
+import { CSS3DSprite } from 'three/examples/jsm/renderers/CSS3DRenderer';
|
|
|
+import { setModalCenter } from '/@/utils/threejs/util';
|
|
|
+// import { setModalCenter } from '/@/utils/threejs/util';
|
|
|
+// import * as dat from 'dat.gui';
|
|
|
+// const gui = new dat.GUI();
|
|
|
+// gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
|
|
|
+
|
|
|
+class ModelContext {
|
|
|
+ model;
|
|
|
+ modelName = 'spray-pensha';
|
|
|
+ // modelName = 'spray-ts';
|
|
|
+ // modelName = 'dedust';
|
|
|
+ group: THREE.Object3D | null = null;
|
|
|
+ /** 本模型内支持的锚点位置数组 */
|
|
|
+ anchors: [number, number, number][] = [
|
|
|
+ [1.5, 0.5, 1.6],
|
|
|
+ // [0, 0, 0],
|
|
|
+ // 右侧传感器
|
|
|
+ [1.3, 0.5, 1.6],
|
|
|
+ // [-25.847, 8.783, 3.267],
|
|
|
+ // [31.142, 8.783, 3.267],
|
|
|
+ ];
|
|
|
+ /** 本模型显示的css详情元素数组 */
|
|
|
+ cssSprites: CSS3DSprite[] = [];
|
|
|
+ /** 初始化时用到的摄像头位置参数,可以供外部访问或初始化时使用 */
|
|
|
+ cameraPostion = {
|
|
|
+ x: 2.0063999826191625,
|
|
|
+ y: 0.3963997081529602,
|
|
|
+ z: 3.275298992446514,
|
|
|
+ };
|
|
|
+ /** 初始化时用到的滑轨目标参数,可以供外部访问或初始化时使用,配合摄像头可以实现更精确的控制 */
|
|
|
+ orbitTarget = {
|
|
|
+ x: 2.023679325280445,
|
|
|
+ y: -0.1461634482645532,
|
|
|
+ z: 0.04677126793423104,
|
|
|
+ };
|
|
|
+
|
|
|
+ constructor(model) {
|
|
|
+ this.model = model;
|
|
|
+ }
|
|
|
+
|
|
|
+ addLight() {
|
|
|
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2);
|
|
|
+ directionalLight.position.set(6.3, 28, 20);
|
|
|
+ this.group?.add(directionalLight);
|
|
|
+ directionalLight.target = this.group as THREE.Object3D;
|
|
|
+
|
|
|
+ const pointLight = new THREE.PointLight(0xffffff, 1, 1000);
|
|
|
+ pointLight.position.set(45, 51, -4.1);
|
|
|
+ pointLight.shadow.bias = 0.05;
|
|
|
+ this.model.scene.add(pointLight);
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 初始化css元素,将css元素选择器传入,该方法会将这些元素按顺序放入本模型支持的锚点中 */
|
|
|
+ initCssElement(selectors: string[]) {
|
|
|
+ selectors.forEach((selector, index) => {
|
|
|
+ const element = document.querySelector(selector) as HTMLElement;
|
|
|
+ if (element) {
|
|
|
+ const css3D = new CSS3DSprite(element);
|
|
|
+ this.cssSprites.push(css3D);
|
|
|
+ css3D.name = selector;
|
|
|
+ css3D.scale.set(0.002, 0.002, 0.002);
|
|
|
+ // const ff = gui.addFolder(`css元素${index}`);
|
|
|
+ // ff.add(css3D.position, 'x', -100, 100);
|
|
|
+ // ff.add(css3D.position, 'y', -100, 100);
|
|
|
+ // ff.add(css3D.position, 'z', -100, 100);
|
|
|
+ if (index < this.anchors.length) {
|
|
|
+ const [x, y, z] = this.anchors[index];
|
|
|
+ css3D.position.set(x, y, z);
|
|
|
+ this.group?.add(css3D);
|
|
|
+ } else {
|
|
|
+ console.warn(`指定的元素${selector}没有合适的位置放置`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 清除css元素 */
|
|
|
+ clearCssElement() {
|
|
|
+ this.cssSprites.forEach((sprite) => {
|
|
|
+ this.group?.remove(sprite);
|
|
|
+ });
|
|
|
+ this.cssSprites = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ mountedThree() {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ this.model.setGLTFModel([this.modelName]).then(async (gltf) => {
|
|
|
+ this.group = gltf[0];
|
|
|
+ if (this.group) {
|
|
|
+ setModalCenter(this.group);
|
|
|
+ resolve(null);
|
|
|
+ // this.addLight();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ destroy() {
|
|
|
+ if (this.model) {
|
|
|
+ this.model.clearGroup(this.group);
|
|
|
+ this.model = null;
|
|
|
+ this.group = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+export default ModelContext;
|