|
@@ -1,102 +1,113 @@
|
|
|
import * as THREE from 'three';
|
|
|
import UseThree from '../../../../utils/threejs/useThree';
|
|
|
-import WorkFace from './dedust.threejs.base';
|
|
|
+import ModelContext from './dedust.threejs.base';
|
|
|
import { animateCamera } from '/@/utils/threejs/util';
|
|
|
import useEvent from '../../../../utils/threejs/useEvent';
|
|
|
|
|
|
-// 模型对象、 文字对象
|
|
|
-let model: UseThree | undefined,
|
|
|
- workFaceObj: WorkFace | undefined,
|
|
|
- group: THREE.Object3D | undefined,
|
|
|
- fiberType = 'tunFace'; // workerFaceFiber
|
|
|
+/** 模型总控制器 */
|
|
|
+let model: UseThree;
|
|
|
+/** 当前展示的具体模型的 Object3D 对象 */
|
|
|
+let group: THREE.Object3D;
|
|
|
+/** 具体模型内容列表,包含此模型总控制器下的所有可用的具体模型内容 */
|
|
|
+const modelContextList: {
|
|
|
+ /** 当前模型类型,在控制器下有多个具体模型时分辨它们 */
|
|
|
+ type: string;
|
|
|
+ /** 模型的具体内容,即负责模型导入、绘制的上下文对象,一个控制器可以新建多个 */
|
|
|
+ context?: ModelContext;
|
|
|
+}[] = [];
|
|
|
const { mouseDownFn } = useEvent();
|
|
|
|
|
|
-// 鼠标点击、松开事件
|
|
|
-const mouseEvent = (event) => {
|
|
|
+/** 分发鼠标事件到具体实现方法 */
|
|
|
+function dispatchMouseEvent(event) {
|
|
|
if (event.button == 0 && model && group) {
|
|
|
mouseDownFn(model, group, event, () => {});
|
|
|
}
|
|
|
-};
|
|
|
-
|
|
|
-const addMouseEvent = () => {
|
|
|
- // 定义鼠标点击事件
|
|
|
- if (!model) return;
|
|
|
- model.canvasContainer?.addEventListener('mousedown', mouseEvent.bind(null));
|
|
|
-};
|
|
|
-
|
|
|
-const render = () => {
|
|
|
- if (model && model.isRender && model.renderer) {
|
|
|
- // model.animationId = requestAnimationFrame(render);
|
|
|
- model.css3dRender?.render(model.scene as THREE.Scene, model.camera as THREE.PerspectiveCamera);
|
|
|
- model.renderer.render(model.scene as THREE.Scene, model.camera as THREE.PerspectiveCamera);
|
|
|
- model.stats?.update();
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-export const refreshModal = () => {
|
|
|
- if (fiberType === 'tunFace') {
|
|
|
- // workFaceObj.render();
|
|
|
- render();
|
|
|
- }
|
|
|
-};
|
|
|
+}
|
|
|
|
|
|
-// 切换风窗类型
|
|
|
-export const setModelType = (type) => {
|
|
|
+/** 初始化模型CSS展示框的鼠标事件,应该在模型总控制器初始化后调用 */
|
|
|
+function initEventListender() {
|
|
|
if (!model) return;
|
|
|
- fiberType = type;
|
|
|
- return new Promise((resolve) => {
|
|
|
- if (fiberType === 'tunFace' && workFaceObj && workFaceObj.group) {
|
|
|
- group = workFaceObj.group;
|
|
|
+ model.canvasContainer?.addEventListener('mousedown', (e) => dispatchMouseEvent(e));
|
|
|
+ // model.orbitControls?.addEventListener('change', () => render());
|
|
|
+}
|
|
|
|
|
|
- // const oldCameraPosition = { x: 124.736, y: 63.486, z: 103.337 };
|
|
|
+/** 渲染并更新总模型 */
|
|
|
+// function render() {
|
|
|
+// if (model && model.isRender && model.renderer) {
|
|
|
+// // model.animationId = requestAnimationFrame(render);
|
|
|
+// model.css3dRender?.render(model.scene as THREE.Scene, model.camera as THREE.PerspectiveCamera);
|
|
|
+// model.renderer.render(model.scene as THREE.Scene, model.camera as THREE.PerspectiveCamera);
|
|
|
+// model.stats?.update();
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
- model?.orbitControls?.addEventListener('change', render);
|
|
|
+/** 刷新(再渲染)总模型 */
|
|
|
+// export function refreshModal() {
|
|
|
+// render();
|
|
|
+// // modelContextList.forEach((item) => {
|
|
|
+// // if (item.context) {
|
|
|
+// // item.context.render();
|
|
|
+// // }
|
|
|
+// // });
|
|
|
+// }
|
|
|
|
|
|
- setTimeout(async () => {
|
|
|
- resolve(null);
|
|
|
- const oldCameraPosition = { x: -693, y: 474, z: 398 };
|
|
|
- if (!model?.scene?.getObjectByName('tunFace') && group) {
|
|
|
- model?.scene?.add(group);
|
|
|
- }
|
|
|
- const position = { x: 14.826074594663222, y: 16.901762713393836, z: 36.459944037951004 };
|
|
|
- await animateCamera(
|
|
|
- oldCameraPosition,
|
|
|
- { x: 0, y: 0, z: 0 },
|
|
|
- { x: position.x, y: position.y, z: position.z },
|
|
|
- { x: 0, y: 0, z: 0 },
|
|
|
- model,
|
|
|
- 0.8,
|
|
|
- render
|
|
|
- );
|
|
|
- }, 400);
|
|
|
- }
|
|
|
+/** 设置模型类型并切换,不同的类型通常对应不同的具体模型,在模型总控制器下的具体模型会根据传入的参数彼此交互、切换 */
|
|
|
+export function setModelType(modelType: 'dedust') {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ if (!model) return reject('模型未初始化');
|
|
|
+ modelContextList.forEach(({ type, context }) => {
|
|
|
+ if (!context) return reject('模型未初始化');
|
|
|
+ if (modelType === type) {
|
|
|
+ group = context?.group as THREE.Object3D;
|
|
|
+ setTimeout(async () => {
|
|
|
+ if (!model.scene?.getObjectByName(type) && group) {
|
|
|
+ model.scene?.add(group);
|
|
|
+ }
|
|
|
+ const oldCameraPosition = { x: -693, y: 474, z: 398 };
|
|
|
+ const position = { x: 14.826074594663222, y: 16.901762713393836, z: 36.459944037951004 };
|
|
|
+ await animateCamera(
|
|
|
+ oldCameraPosition,
|
|
|
+ { x: 0, y: 0, z: 0 },
|
|
|
+ { x: position.x, y: position.y, z: position.z },
|
|
|
+ { x: 0, y: 0, z: 0 },
|
|
|
+ model,
|
|
|
+ 0.8
|
|
|
+ );
|
|
|
+ resolve(null);
|
|
|
+ }, 400);
|
|
|
+ }
|
|
|
+ });
|
|
|
});
|
|
|
-};
|
|
|
+}
|
|
|
|
|
|
-export const mountedThree = () => {
|
|
|
+/** 挂载模型控制器,sceneSelctor表示放置模型的元素选择器,cssSelectors表示放置类似详情框的元素选择器,其中第一项需要是根元素选择器 */
|
|
|
+export function mountedThree(sceneSelctor: string, cssSelectors: string[]) {
|
|
|
return new Promise(async (resolve) => {
|
|
|
- model = new UseThree('#tunFace3D', '#tunFace3DCSS');
|
|
|
+ const [rootSelector, ...selectors] = cssSelectors;
|
|
|
+ model = new UseThree(sceneSelctor, rootSelector);
|
|
|
model.setEnvMap('test1.hdr');
|
|
|
/** @ts-ignore-next-line */
|
|
|
model.renderer.toneMappingExposure = 1.0;
|
|
|
- // model?.camera?.position.set(100, 0, 1000);
|
|
|
- workFaceObj = new WorkFace(model);
|
|
|
- await workFaceObj.mountedThree();
|
|
|
|
|
|
- addMouseEvent();
|
|
|
- // render();
|
|
|
+ const model1 = new ModelContext(model);
|
|
|
+ await model1.mountedThree();
|
|
|
+ model1.initCssElement(selectors);
|
|
|
+ modelContextList.push({
|
|
|
+ type: 'dedust',
|
|
|
+ context: model1,
|
|
|
+ });
|
|
|
+
|
|
|
+ initEventListender();
|
|
|
model.animate();
|
|
|
resolve(null);
|
|
|
});
|
|
|
-};
|
|
|
+}
|
|
|
|
|
|
export const destroy = () => {
|
|
|
- if (model) {
|
|
|
- model.isRender = false;
|
|
|
- workFaceObj?.destroy();
|
|
|
- workFaceObj = undefined;
|
|
|
- group = undefined;
|
|
|
- model.destroy();
|
|
|
- model = undefined;
|
|
|
- }
|
|
|
+ if (!model) return;
|
|
|
+ model.isRender = false;
|
|
|
+ modelContextList.forEach((item) => {
|
|
|
+ if (item.context) item.context.destroy();
|
|
|
+ });
|
|
|
+ model.destroy();
|
|
|
};
|