fuseMode.ts 8.3 KB

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