fuseMode.ts 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. import { SDK, SceneModel, ModelAttrRange } from "../sdk";
  2. import { toRaw, watch, reactive, ref, watchEffect } from "vue";
  3. import { custom, getResource } from "@/env";
  4. import {
  5. diffArrayChange,
  6. shallowWatchArray,
  7. arrayChildEffectScope,
  8. showLoad,
  9. hideLoad,
  10. deepIsRevise,
  11. round,
  12. } from "@/utils";
  13. import {
  14. dynamicAddedModelIds,
  15. fuseModels,
  16. getFuseModelShowVariable,
  17. SceneType,
  18. SceneStatus,
  19. FuseModel,
  20. FuseModels,
  21. } from "@/store";
  22. import { currentLayout, RoutesName } from "@/router";
  23. import { unsetFactory } from "@/utils/unset";
  24. const us = unsetFactory()
  25. // -----------------模型关联--------------------
  26. export const modelRange: ModelAttrRange = {
  27. opacityRange: { min: 0, max: 100, step: 0.1 },
  28. bottomRange: { min: -30, max: 70, step: 0.1 },
  29. scaleRange: { min: 0.1, max: 200, step: 0.1 },
  30. };
  31. export const sceneModelMap = reactive(new Map<FuseModel, SceneModel>());
  32. export const getSceneModel = (model?: FuseModel | null) =>
  33. model && sceneModelMap.get(toRaw(model));
  34. export const getFuseModel = (model?: SceneModel | null) => {
  35. if (!model) return null;
  36. for (const [k, v] of sceneModelMap.entries()) {
  37. if (toRaw(v) === toRaw(model)) {
  38. return k;
  39. }
  40. }
  41. };
  42. const setModels = (sdk: SDK, models: FuseModels, oldModels: FuseModels) => {
  43. const { added, deleted } = diffArrayChange(models, oldModels);
  44. for (const item of added) {
  45. if (getSceneModel(item)) {
  46. continue;
  47. }
  48. if (item.status !== SceneStatus.SUCCESS) {
  49. item.error = true;
  50. item.loaded = true;
  51. continue;
  52. }
  53. const itemRaw = toRaw(item);
  54. let sceneModel: SceneModel;
  55. try {
  56. sceneModel = sdk.addModel({
  57. ...itemRaw,
  58. ...modelRange,
  59. mode: RoutesName.signModel === currentLayout.value! ? "single" : "many",
  60. isDynamicAdded: dynamicAddedModelIds.value.some(
  61. (id) => itemRaw.id === id
  62. ),
  63. type: [SceneType.SWSS, SceneType.SWYDSS].includes(item.type)
  64. ? "laser"
  65. : item.modelType,
  66. url: [SceneType.SWSS, SceneType.SWYDSS].includes(item.type)
  67. ? item.url
  68. : item.url && item.url.map(getResource),
  69. fromType: item.type,
  70. });
  71. } catch (e) {
  72. console.error("模型加载失败", e);
  73. item.error = true;
  74. return;
  75. }
  76. sceneModelMap.set(itemRaw, sceneModel);
  77. let changeId: NodeJS.Timeout;
  78. sceneModel.bus.on("transformChanged", (transform) => {
  79. clearTimeout(changeId);
  80. changeId = setTimeout(() => {
  81. transform = { ...transform };
  82. if (transform.rotation) {
  83. transform.rotation = {
  84. x: round(transform.rotation.x, 5),
  85. y: round(transform.rotation.y, 5),
  86. z: round(transform.rotation.z, 5),
  87. };
  88. }
  89. if (transform.position) {
  90. transform.position = {
  91. x: round(transform.position.x, 5),
  92. y: round(transform.position.y, 5),
  93. z: round(transform.position.z, 5),
  94. };
  95. }
  96. delete transform.bottom;
  97. // if (transform.bottom) {
  98. // transform.bottom = round(transform.bottom, 2)
  99. // }
  100. if (transform.scale) {
  101. transform.scale = round(transform.scale, 2);
  102. }
  103. const updateKeys = Object.keys(transform);
  104. const update: any = {};
  105. for (const key of updateKeys) {
  106. update[key] = (item as any)[key];
  107. }
  108. if (deepIsRevise(update, transform)) {
  109. console.error('change', item)
  110. us.unSet(() => Object.assign(item, transform));
  111. }
  112. }, 16);
  113. });
  114. sceneModel.bus.on("changeSelect", (select) => {
  115. us.unSet(() => {
  116. // if (custom.showMode === "fuse") {
  117. if (custom.currentModel === item && !select) {
  118. custom.currentModel = null;
  119. } else if (custom.currentModel !== item && select) {
  120. custom.currentModel = item;
  121. }
  122. // }
  123. });
  124. });
  125. showLoad();
  126. sceneModel.bus.on("loadDone", () => {
  127. item.loaded = true;
  128. hideLoad();
  129. });
  130. sceneModel.bus.on("loadError", () => {
  131. item.error = true;
  132. item.show = false;
  133. custom.showModelsMap.delete(item);
  134. hideLoad();
  135. });
  136. sceneModel.bus.on("loadProgress", (progress) => (item.progress = progress));
  137. }
  138. for (const item of deleted) {
  139. console.error("销毁", item);
  140. getSceneModel(item)?.destroy();
  141. sceneModelMap.delete(item);
  142. }
  143. };
  144. export const activeModel = (status: {
  145. showMode: "fuse" | "pano";
  146. active?: FuseModel;
  147. fore?: boolean
  148. }) => {
  149. const oldStatus = {
  150. showMode: custom.showMode,
  151. active: custom.currentModel,
  152. };
  153. if (
  154. toRaw(status.active) === toRaw(oldStatus.active) &&
  155. status.showMode === oldStatus.showMode
  156. ) {
  157. return;
  158. }
  159. const model = status.active && getSceneModel(status.active)!;
  160. const oldModel = oldStatus.active && getSceneModel(oldStatus.active)!;
  161. if (oldModel) {
  162. oldModel.changeSelect(false);
  163. }
  164. if (model && status.active === oldStatus.active) {
  165. if (status.showMode === "pano") {
  166. if (model) {
  167. console.error('--->', model)
  168. model.changeSelect(false)
  169. model.flyInPano();
  170. }
  171. } else {
  172. if (model) {
  173. model.flyOutPano();
  174. custom.currentModel === status.active && model.changeSelect(true)
  175. }
  176. }
  177. } else {
  178. if (oldStatus.showMode !== status.showMode) {
  179. if (oldStatus.showMode === "pano") {
  180. if (oldModel) {
  181. console.error('---> a', oldModel)
  182. oldModel.flyOutPano();
  183. custom.currentModel === oldStatus.active && oldModel.changeSelect(true)
  184. }
  185. }
  186. }
  187. if (status.showMode === "pano") {
  188. if (model) {
  189. console.error('---> b', oldModel)
  190. model.changeSelect(false)
  191. model.flyInPano();
  192. }
  193. } else {
  194. console.log("select");
  195. }
  196. }
  197. setTimeout(() => {
  198. if (status.showMode !== "pano" && model) {
  199. if (oldStatus.showMode !== 'pano' || status.fore) {
  200. model && model.changeSelect(true);
  201. }
  202. }
  203. }, 35);
  204. custom.currentModel = status.active!;
  205. custom.showMode = status.showMode;
  206. };
  207. export const associationModels = (sdk: SDK) => {
  208. sdk.sceneBus.on("modeChange", (data) => {
  209. if (data.active || data.model) {
  210. activeModel({ active: getFuseModel(data.active || data.model)!, showMode: data.mode })
  211. }
  212. custom.showMode = data.mode;
  213. console.error('modeChange', data, (data.active || data.model))
  214. if ((data.active || data.model) && data.mode === 'pano') {
  215. (data.active || data.model).changeSelect(false)
  216. }
  217. });
  218. sdk.sceneBus.on("panoModelChange", (data) => {
  219. custom.showMode = "pano";
  220. custom.currentModel = getFuseModel(data)!;
  221. data.changeSelect(false)
  222. // activeModel({ active: getFuseModel(data)!, showMode: 'pano' })
  223. });
  224. const getModels = () =>
  225. fuseModels.value.filter(
  226. (model) => getSceneModel(model) || getFuseModelShowVariable(model).value
  227. );
  228. shallowWatchArray(getModels, (models, oldModels) => {
  229. setModels(sdk, models, oldModels);
  230. });
  231. arrayChildEffectScope(getModels, (item) => {
  232. const stopLoadedWatch = watch(
  233. () => item.loaded,
  234. (loaded) => {
  235. if (loaded) {
  236. const modelShow = getFuseModelShowVariable(item);
  237. watch(
  238. () => item.bottom,
  239. () => us.isUnSet || getSceneModel(item)?.changeBottom(item.bottom)
  240. // { immediate: true }
  241. );
  242. watch(
  243. () => item.opacity,
  244. () => us.isUnSet || getSceneModel(item)?.changeOpacity(item.opacity)
  245. // { immediate: true }
  246. );
  247. watch(
  248. () => item.scale,
  249. () => {
  250. us.isUnSet || getSceneModel(item)?.changeScale(item.scale)
  251. }
  252. // { immediate: true }
  253. );
  254. watch(
  255. () => item.position,
  256. () => {
  257. if (!us.isUnSet) {
  258. console.log('position', item.raw.modelTitle, toRaw(item.position))
  259. getSceneModel(item)?.changePosition(item.position);
  260. }
  261. }
  262. // { immediate: true }
  263. );
  264. watch(
  265. () => item.rotation,
  266. () => {
  267. if (!us.isUnSet) {
  268. console.log('rotation', item.raw.modelTitle, toRaw(item.rotation))
  269. getSceneModel(item)?.changeRotation(toRaw(item.rotation));
  270. }
  271. }
  272. // { immediate: true }
  273. );
  274. watch(
  275. () => modelShow.value,
  276. () => {
  277. const sceneModel = getSceneModel(item);
  278. if (!us.isUnSet && sceneModel) {
  279. sceneModel.changeSelect(false);
  280. sceneModel.changeShow(modelShow.value);
  281. }
  282. },
  283. { immediate: true }
  284. );
  285. stopLoadedWatch();
  286. }
  287. }
  288. // { immediate: true }
  289. );
  290. });
  291. };
  292. export const getSupportPano = (model: FuseModel) => {
  293. const supportPano = ref(false);
  294. const show = getFuseModelShowVariable(model);
  295. watchEffect(() => {
  296. if (!show.value) {
  297. supportPano.value = false;
  298. return;
  299. }
  300. const sceneModel = getSceneModel(model);
  301. const support = sceneModel?.supportPano();
  302. supportPano.value = !!support;
  303. sceneModel?.bus.on("loadDone", () => {
  304. supportPano.value = sceneModel?.supportPano();
  305. });
  306. });
  307. return supportPano
  308. }