loadModel - 副本.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. var app = getApp(); //获取应用实例
  2. const util = require('@/static/utils/util.js');
  3. const config = require('@/static/config.js');
  4. import modelData from '@/webgl/static/layoutModelData.js';
  5. // import requestConfig from '@/services/requestConfig.js';
  6. const THREE = requirePlugin('ThreeX');
  7. // import { TWEEN } from '@/webgl/jsm/libs/tween.module.min.js';
  8. export default {
  9. data() {
  10. return {
  11. gltfLayouts: [],
  12. instancedFurList:[],
  13. arrFrunList:[],
  14. promise_list:[],
  15. loadFurPromise: new Promise((resolve) => {
  16. this.loadedCompleteFun = function() {
  17. console.log('家具模型接口结束');
  18. resolve()
  19. }
  20. }),
  21. }
  22. },
  23. watch: {},
  24. onReady() {
  25. },
  26. methods: {
  27. // 设置空间数组的墙体信息
  28. async setSpaceListWallInfo(){
  29. for (let index = 0; index < this.spaceList.length; index++) {
  30. let spaceWallInfo = {wallN:false, wallS:false, wallW:false, wallE:false}
  31. const element = this.spaceList[index];
  32. const wallWIndex = this.gltfWalls.findIndex(item=>{
  33. return element.spaceId == item.spaceId && item.wallDirection == "W"
  34. })
  35. spaceWallInfo.wallW = wallWIndex == -1 ? false : true;
  36. const wallEIndex = this.gltfWalls.findIndex(item=>{
  37. return element.spaceId == item.spaceId && item.wallDirection == "E"
  38. })
  39. spaceWallInfo.wallE = wallEIndex == -1 ? false : true;
  40. const wallNIndex = this.gltfWalls.findIndex(item=>{
  41. return element.spaceId == item.spaceId && item.wallDirection == "N"
  42. })
  43. spaceWallInfo.wallN = wallNIndex == -1 ? false : true;
  44. const wallSIndex = this.gltfWalls.findIndex(item=>{
  45. return element.spaceId == item.spaceId && item.wallDirection == "S"
  46. })
  47. spaceWallInfo.wallS = wallSIndex == -1 ? false : true;
  48. element.spaceWallInfo = spaceWallInfo;
  49. }
  50. await this.loadFurPromise;//等待解析分享者参数结束
  51. this.$nextTick(() => {
  52. this.calculateLayoutModelSize() // 计算模型的位置
  53. })
  54. },
  55. // 批量获取空间模型信息
  56. async getOverallArrangementDetailsList() {
  57. // 设置空间数组的墙体信息
  58. // this.setSpaceListWallInfo();
  59. let arr = this.spaceList.map(it => it.layoutId).filter(it => it != 0);
  60. let parmas = {
  61. ids: arr,
  62. };
  63. this.loadFurPromise = new Promise((resolve, reject) => {
  64. this.loadedCompleteFun = function() {
  65. console.log('家具模型接口结束');
  66. resolve()
  67. }
  68. })
  69. let res = await requestConfig("getOverallArrangementDetailsList", parmas);
  70. if (!res.success || !res.list || res.list.length == 0) {
  71. return false;
  72. }
  73. this.promise_list = [];
  74. this.arrFrunList = res.list;
  75. this.furnHandle();
  76. },
  77. //拆分家具模型加载逻辑
  78. furnHandle(){
  79. let startTime = new Date().getTime();
  80. let tmpList = [];//临时数据
  81. this.gltfLayouts = []; //模型列表,所有空间里面的每个模型(家具)对应一条记录
  82. let allowSpaceId = [this.curSpaceObj.spaceId];
  83. if(this.curSpaceObj.spaceId==758){//二层主卧特殊处理
  84. allowSpaceId.push(735);//休闲小客厅
  85. }
  86. //花园类型的添加到家具加载目录里面
  87. // this.spaceList.forEach(it=>{
  88. // if(it.spaceType==14){
  89. // allowSpaceId.push(it.spaceId);
  90. // }
  91. // })
  92. this.arrFrunList.forEach(signel => {
  93. let spaceId = this.spaceList.find(it => it.layoutId == signel.id).spaceId;
  94. if(allowSpaceId.includes(spaceId)){//只加载允许的空间的布局,其他不加载
  95. let md = JSON.parse(signel.modelJson); //获取布局里面的模型信息
  96. console.warn("***布局***", md, signel.id)
  97. //遍历模型信息,获取模型列表
  98. for (let i = 0; i < md.modelData.length; i++) {
  99. let item = md.modelData[i];
  100. item.spaceId = spaceId;
  101. item.layoutId = signel.id;
  102. // tmpList.push(item);
  103. this.promise_list.push(
  104. new Promise((resolve, reject) => {
  105. this.loadLayoutModelsOld(item , resolve);
  106. })
  107. )
  108. }
  109. }
  110. })
  111. // let realFurArr = this.preFurnitureData(tmpList);//统一处理家具模型
  112. // let arrLength = realFurArr.length;
  113. // console.log("***realFurArr***", realFurArr);
  114. // realFurArr && realFurArr.forEach((item,index) => {
  115. // this.promise_list.push(
  116. // new Promise((resolve, reject) => {
  117. // this.loadLayoutModels(item, arrLength , resolve);
  118. // })
  119. // )
  120. // });
  121. Promise.all(this.promise_list).then(() => {
  122. let endTime = new Date().getTime();
  123. console.log("家具模型全部加载完成,时间:", endTime - startTime);
  124. this.loadedCompleteFun()
  125. // this.$nextTick(() => {
  126. // this.calculateLayoutModelSize() // 计算模型的位置
  127. // })
  128. })
  129. },
  130. //预处理需要加载墙体模型的数据-减少模型请求数
  131. preFurnitureData(list){
  132. let realFurnitureArr = [];//家具列表
  133. let dataList = [];
  134. dataList = list.map(item=>{
  135. let curSpace = this.spaceList.find(space=>space.spaceId==item.spaceId);
  136. return this.resetModelParameters(curSpace, item);
  137. })
  138. dataList && dataList.forEach((item, index) => {
  139. item.uniId = Date.now() + index;//唯一标识
  140. //获取墙体对应的gltb模型的相关信息
  141. let modelName = item.modelName;
  142. // console.log("布局模型名称", modelName);
  143. let layoutModel = modelData.find(it => modelName.indexOf(it.modelName) == 0); //模型地址
  144. if (layoutModel && layoutModel.url) {//该数据存在模型地址
  145. let object = realFurnitureArr.find(it=>it.url==layoutModel.url);
  146. //列表中还没有这个数据
  147. if(!object){
  148. let it = {
  149. url:layoutModel.url,
  150. name:layoutModel.modelName,
  151. list:[item],
  152. }
  153. realFurnitureArr.push(it)
  154. }else{
  155. object.list.push(item);
  156. }
  157. }
  158. });
  159. return realFurnitureArr;
  160. },
  161. //加载家具模型-实例化方案
  162. loadLayoutModels(realData, arrLength, resolve){
  163. var that = this;
  164. if(!realData.url){
  165. console.warn("***家具模型不存在***",realData);
  166. resolve();
  167. return false;
  168. }
  169. that.loader.load(realData.url, ( gltf ) => {
  170. // that.progress = parseInt(100/arrLength) + that.progress;
  171. // if(that.progress>100){
  172. // that.progress = 100;
  173. // }
  174. // that.$refs.myLoading.showLoading("加载中..." + that.progress+'%')
  175. // console.log("家具加载成功",that.progress,realData,gltf);
  176. gltf.scene.traverse((child)=> {
  177. if (child.isMesh && child.visible) {
  178. let instancedMesh = new THREE.InstancedMesh(child.geometry.clone(), child.material.clone(), realData.list.length);
  179. this.instancedFurList.push(instancedMesh);
  180. //realData 该模型被重复使用时的每一次的形变参数等
  181. realData.list && realData.list.forEach((it,i)=>{
  182. let rotationY = Math.PI / 2;
  183. if (parseFloat(it.rotation) == 90) {
  184. rotationY = 0;
  185. }
  186. if (parseFloat(it.rotation) == 180) {
  187. rotationY = -Math.PI / 2;
  188. }
  189. if (parseFloat(it.rotation) == -90) {
  190. rotationY = -Math.PI;
  191. }
  192. gltf.scene.rotation.y = rotationY;
  193. gltf.scene.updateMatrixWorld();//更新世界坐标-这样,子模型也同步更新了
  194. instancedMesh.setMatrixAt(i, child.matrixWorld);
  195. instancedMesh.instanceMatrix.needsUpdate = true;
  196. // instancedMesh.setColorAt(i, child.material.color);
  197. // instancedMesh.instanceColor.needsUpdate = true;
  198. let gltfFurn = that.gltfLayouts.find(itme=>itme.uniId==it.uniId);//判断是否已经添加过
  199. if(!gltfFurn){
  200. let position = new THREE.Vector3();//当前几何体的位置参数
  201. let scale = new THREE.Vector3();//当前几何体的缩放参数
  202. let rotation = new THREE.Vector3();//当前几何体的缩放参数
  203. let md = {
  204. uniId:it.uniId,//家具模型实例的唯一标识
  205. spaceId:it.spaceId,
  206. id:it.id,
  207. instancedMeshIndexList:[//标识网格实例数组的序号 以及 当前几何体 在网格实例的序号
  208. {instancedMeshIndex:this.instancedFurList.length-1,instancedAtIndex:i},
  209. ],
  210. userData:it,
  211. position:position,
  212. scale:scale,
  213. rotation:rotation,
  214. loaded:false,
  215. };
  216. that.gltfLayouts.push(md);
  217. }else{
  218. gltfFurn.instancedMeshIndexList.push({
  219. instancedMeshIndex:this.instancedFurList.length-1,instancedAtIndex:i
  220. })
  221. }
  222. })
  223. instancedMesh.userType = "layoutMesh";
  224. }
  225. });
  226. resolve();
  227. });
  228. },
  229. //加载模型
  230. loadLayoutModelsOld(modelObj, resolve) {
  231. let that = this;
  232. const modelName = modelObj.modelName;
  233. console.log("布局模型名称", modelName);
  234. let layoutModel = modelData.find(it => modelName.indexOf(it.modelName) == 0); //模型地址
  235. if (!layoutModel || !layoutModel.url) {
  236. resolve();
  237. return false
  238. }
  239. let url = layoutModel.url;
  240. console.log("布局模型数据", layoutModel);
  241. that.loader.load(url, (gltf) => {
  242. // console.log("布局模型加载成功", gltf);
  243. let model = gltf.scene; // 获取模型
  244. model.name = layoutModel.modelName;
  245. model.userType = "layoutMesh";
  246. model.userData = modelObj;
  247. // model.rotation.y = Math.PI / 2 ; // 旋转 90 度
  248. this.gltfLayouts.push(model);
  249. resolve();
  250. });
  251. },
  252. // 计算家具的位置
  253. calculateLayoutModelSize() {
  254. console.log("计算家具的位置", this.gltfLayouts);
  255. for (let index = 0; index < this.spaceList.length; index++) {
  256. const element = this.spaceList[index];
  257. const gltfLayoutModels = this.gltfLayouts.filter(item => {
  258. return element.layoutId == item.userData.layoutId && element.spaceId == item.userData.spaceId;
  259. })
  260. //空间下不存在家具模型,则该空间不需要进行下一步处理
  261. if (!gltfLayoutModels || gltfLayoutModels.length == 0) {
  262. continue;
  263. }
  264. gltfLayoutModels.sort(function(a, b) {
  265. return a.userData.level - b.userData.level
  266. });
  267. // console.log("对应空间ID的模型数组", this.gltfLayouts, element.spaceId, gltfLayoutModels)
  268. for (let j = 0; j < gltfLayoutModels.length; j++) {
  269. const cube = gltfLayoutModels[j];
  270. this.drawLayoutModel(element, cube);
  271. }
  272. }
  273. },
  274. // 绘制模型
  275. drawLayoutModel(curSpace, cube) {
  276. const {
  277. centerX,
  278. spaceId
  279. } = curSpace;
  280. const cubeInfo = this.resetModelParameters(curSpace, cube.userData);
  281. // const cubeInfo = cube.userData;
  282. let centerY = curSpace.centerY * -1; // UE和ThreeJS坐标做相反
  283. // 默认空间中心点
  284. let positionX = centerX;
  285. let positionY = centerY;
  286. let rotationY = Math.PI / 2;
  287. let scaleX = 1;
  288. let scaleY = 1;
  289. // 空间尺寸
  290. let spaceWidth = curSpace.spaceWidth;
  291. let spaceHeight = curSpace.spaceHeight;
  292. // 模型尺寸
  293. let modelWidth = cubeInfo.modelWidth;
  294. let modelHeight = cubeInfo.modelHeight;
  295. // // 判断旋转
  296. if (parseFloat(cubeInfo.rotation) == 90) {
  297. rotationY = 0;
  298. // 交换尺寸
  299. // modelWidth = cubeInfo.modelHeight;
  300. // modelHeight = cubeInfo.modelWidth;
  301. }
  302. if (parseFloat(cubeInfo.rotation) == 180) {
  303. rotationY = -Math.PI / 2;
  304. // modelWidth = cubeInfo.modelHeight;
  305. // modelHeight = cubeInfo.modelWidth;
  306. }
  307. if (parseFloat(cubeInfo.rotation) == -90) {
  308. rotationY = -Math.PI;
  309. // 交换尺寸
  310. // modelWidth = cubeInfo.modelHeight;
  311. // modelHeight = cubeInfo.modelWidth;
  312. }
  313. // 判断靠墙
  314. if (cubeInfo.isStepAsideLeft == 'true') {
  315. positionX = centerX - (spaceWidth / 2 - modelWidth / 2);
  316. if (parseFloat(cubeInfo.rotation) == 90 || parseFloat(cubeInfo.rotation) == -90) {
  317. positionX = centerX - (spaceWidth / 2 - modelWidth / 2);
  318. }
  319. positionX += parseFloat(cubeInfo.marginLeft);
  320. positionX += curSpace.spaceWallInfo.wallW ? 10 : 0;
  321. }
  322. if (cubeInfo.isStepAsideRight == 'true') {
  323. positionX = centerX + (spaceWidth / 2 - modelHeight / 2);
  324. if (parseFloat(cubeInfo.rotation) == 90 || parseFloat(cubeInfo.rotation) == -90) {
  325. positionX = centerX + (spaceWidth / 2 - modelWidth / 2);
  326. }
  327. positionX -= parseFloat(cubeInfo.marginRight);
  328. positionX -= curSpace.spaceWallInfo.wallE ? 10 : 0;
  329. }
  330. if (cubeInfo.isStepAsideTop == 'true') {
  331. positionY = centerY - (spaceHeight / 2 - modelWidth / 2);
  332. if (parseFloat(cubeInfo.rotation) == 90 || parseFloat(cubeInfo.rotation) == -90) {
  333. positionY = centerY - (spaceHeight / 2 - modelHeight / 2);
  334. }
  335. positionY += parseFloat(cubeInfo.marginTop);
  336. positionY += curSpace.spaceWallInfo.wallN ? 10 : 0;
  337. }
  338. if (cubeInfo.isStepAsideBottom == 'true') {
  339. positionY = centerY + (spaceHeight / 2 - modelHeight / 2);
  340. if (parseFloat(cubeInfo.rotation) == 90 || parseFloat(cubeInfo.rotation) == -90) {
  341. positionY = centerY + (spaceHeight / 2 - modelHeight / 2);
  342. }
  343. positionY -= parseFloat(cubeInfo.marginBottom);
  344. positionY -= curSpace.spaceWallInfo.wallS ? 10 : 0;
  345. }
  346. // 参照物
  347. if (parseInt(cubeInfo.referenceModelTop) > 0) {
  348. const referenceModel = this.gltfLayouts.find(item => {
  349. const layoutModelData = item.userData;
  350. return layoutModelData.id == parseInt(cubeInfo.referenceModelTop) && layoutModelData
  351. .spaceId == cubeInfo.spaceId && layoutModelData.layoutId == cubeInfo.layoutId;
  352. })
  353. positionY = referenceModel.position.z * 100 + (referenceModel.userData.modelHeight / 2 + cubeInfo
  354. .modelHeight / 2);
  355. positionY = positionY + parseFloat(cubeInfo.marginTop);
  356. }
  357. if (parseInt(cubeInfo.referenceModelBottom) > 0) {
  358. const referenceModel = this.gltfLayouts.find(item => {
  359. const layoutModelData = item.userData;
  360. return layoutModelData.id == parseInt(cubeInfo.referenceModelBottom) && layoutModelData
  361. .spaceId == cubeInfo.spaceId && layoutModelData.layoutId == cubeInfo.layoutId;
  362. })
  363. positionY = referenceModel.position.z * 100 - (referenceModel.userData.modelHeight / 2 + cubeInfo
  364. .modelHeight / 2);
  365. positionY = positionY - parseFloat(cubeInfo.marginBottom);
  366. }
  367. if (parseInt(cubeInfo.referenceModelLeft) > 0) {
  368. const referenceModel = this.gltfLayouts.find(item => {
  369. const layoutModelData = item.userData;
  370. return layoutModelData.id == parseInt(cubeInfo.referenceModelLeft) && layoutModelData
  371. .spaceId == cubeInfo.spaceId && layoutModelData.layoutId == cubeInfo.layoutId;
  372. })
  373. positionX = referenceModel.position.x * 100 + (referenceModel.userData.modelWidth / 2 + cubeInfo
  374. .modelWidth / 2);
  375. positionX = positionX + parseFloat(cubeInfo.marginLeft);
  376. }
  377. if (parseInt(cubeInfo.referenceModelRight) > 0) {
  378. const referenceModel = this.gltfLayouts.find(item => {
  379. const layoutModelData = item.userData;
  380. return layoutModelData.id == parseInt(cubeInfo.referenceModelRight) && layoutModelData
  381. .spaceId == cubeInfo.spaceId && layoutModelData.layoutId == cubeInfo.layoutId;
  382. })
  383. positionX = referenceModel.position.x * 100 - (referenceModel.userData.modelWidth / 2 + cubeInfo
  384. .modelWidth / 2);
  385. positionX = positionX - parseFloat(cubeInfo.marginRight);
  386. }
  387. if (cubeInfo.isFixedWidth == "false" || cubeInfo.isFixedHeight == "false") { // 固定尺寸
  388. // 靠墙拉伸
  389. if (cubeInfo.isStepAsideTop == 'true' && cubeInfo.isStepAsideBottom == 'true') {
  390. // console.log("高度拉伸", spaceHeight / modelHeight)
  391. positionY = centerY;
  392. if (curSpace.spaceWallInfo.wallN && curSpace.spaceWallInfo.wallS) {
  393. spaceHeight -= 20 + parseFloat(cubeInfo.marginTop) + parseFloat(cubeInfo.marginBottom);
  394. } else if (curSpace.spaceWallInfo.wallN) {
  395. spaceHeight -= 10 + parseFloat(cubeInfo.marginTop);
  396. positionY += 10 / 2;
  397. positionY += parseFloat(cubeInfo.marginTop) / 2;
  398. } else if (curSpace.spaceWallInfo.wallS) {
  399. spaceHeight -= 10 + parseFloat(cubeInfo.marginBottom);
  400. positionY -= 10 / 2;
  401. positionY -= parseFloat(cubeInfo.marginBottom) / 2;
  402. }else {
  403. spaceHeight -= parseFloat(cubeInfo.marginTop) + parseFloat(cubeInfo.marginBottom);
  404. positionY += parseFloat(cubeInfo.marginTop) / 2 ;
  405. positionY -= parseFloat(cubeInfo.marginBottom) / 2;
  406. }
  407. // 计算缩放
  408. if (parseFloat(cubeInfo.rotation) == 90 || parseFloat(cubeInfo.rotation) == -90) {
  409. scaleY = spaceHeight / modelHeight;
  410. } else {
  411. scaleX = spaceHeight / modelHeight;
  412. }
  413. }
  414. if (cubeInfo.isStepAsideLeft == 'true' && cubeInfo.isStepAsideRight == 'true') {
  415. // console.log("宽度拉伸11111", spaceWidth / modelWidth)
  416. positionX = centerX;
  417. if (curSpace.spaceWallInfo.wallW && curSpace.spaceWallInfo.wallE) {
  418. spaceWidth -= 20 + parseFloat(cubeInfo.marginLeft) + parseFloat(cubeInfo.marginRight);;
  419. } else if (curSpace.spaceWallInfo.wallW) {
  420. spaceWidth -= 10 + parseFloat(cubeInfo.marginLeft);
  421. positionX += 10 / 2;
  422. positionX += parseFloat(cubeInfo.marginLeft) / 2;
  423. } else if (curSpace.spaceWallInfo.wallE) {
  424. spaceWidth -= 10 + parseFloat(cubeInfo.marginRight);
  425. positionX -= 10 / 2;
  426. positionX -= parseFloat(cubeInfo.marginRight) / 2;
  427. }else {
  428. spaceWidth -= parseFloat(cubeInfo.marginLeft) + parseFloat(cubeInfo.marginRight);
  429. positionX += parseFloat(cubeInfo.marginLeft) / 2;
  430. positionX -= parseFloat(cubeInfo.marginRight) / 2;
  431. }
  432. // console.log("模型计算位置" , parseFloat(cubeInfo.rotation))
  433. // 计算缩放
  434. if (parseFloat(cubeInfo.rotation) == 90 || parseFloat(cubeInfo.rotation) == -90) {
  435. scaleX = spaceWidth / modelWidth;
  436. } else {
  437. scaleY = spaceWidth / modelWidth;
  438. }
  439. }
  440. // 单个参照物和墙面拉伸
  441. if (cubeInfo.isStepAsideTop == 'true' && parseInt(cubeInfo.referenceModelBottom) > 0) {
  442. const referenceModel = this.gltfLayouts.find(item => {
  443. const layoutModelData = item.userData;
  444. return layoutModelData.id == parseInt(cubeInfo.referenceModelBottom) && layoutModelData
  445. .spaceId == cubeInfo.spaceId && layoutModelData.layoutId == cubeInfo.layoutId;
  446. })
  447. const referenceModelPositionY = referenceModel.position.z * 100 - referenceModel.userData
  448. .modelHeight / 2 - parseFloat(cubeInfo.marginBottom);
  449. const wallPositionY = centerY - spaceHeight / 2 + (curSpace.spaceWallInfo.wallN ? 10 : 0) +
  450. parseFloat(cubeInfo.marginTop);
  451. const newModelHeight = Math.abs(referenceModelPositionY - wallPositionY);
  452. // console.log("上边拉伸", referenceModelPositionY, wallPositionY, newModelHeight)
  453. if (Math.abs(parseFloat(cubeInfo.rotation)) == 90) {
  454. scaleY = newModelHeight / modelHeight;
  455. } else {
  456. scaleX = newModelHeight / modelHeight;
  457. }
  458. positionY = wallPositionY + newModelHeight / 2;
  459. }
  460. if (cubeInfo.isStepAsideBottom == 'true' && parseInt(cubeInfo.referenceModelTop) > 0) {
  461. const referenceModel = this.gltfLayouts.find(item => {
  462. const layoutModelData = item.userData;
  463. return layoutModelData.id == parseInt(cubeInfo.referenceModelTop) && layoutModelData
  464. .spaceId == cubeInfo.spaceId && layoutModelData.layoutId == cubeInfo.layoutId;
  465. })
  466. const referenceModelPositionY = referenceModel.position.z * 100 + referenceModel.userData
  467. .modelHeight / 2 + parseFloat(cubeInfo.marginTop) + (curSpace.spaceWallInfo.wallN ? 10 : 0);
  468. const wallPositionY = centerY + spaceHeight / 2 - (curSpace.spaceWallInfo.wallS ? 10 : 0) -
  469. parseFloat(cubeInfo.marginBottom);
  470. const newModelHeight = Math.abs(referenceModelPositionY - wallPositionY);
  471. if (Math.abs(parseFloat(cubeInfo.rotation)) == 90) {
  472. scaleY = newModelHeight / modelHeight;
  473. } else {
  474. scaleX = newModelHeight / modelHeight;
  475. }
  476. positionY = wallPositionY - newModelHeight / 2;
  477. }
  478. if (cubeInfo.isStepAsideLeft == 'true' && parseInt(cubeInfo.referenceModelRight) > 0) {
  479. // console.log("左边拉伸")
  480. const referenceModel = this.gltfLayouts.find(item => {
  481. const layoutModelData = item.userData;
  482. return layoutModelData.id == parseInt(cubeInfo.referenceModelRight) && layoutModelData
  483. .spaceId == cubeInfo.spaceId && layoutModelData.layoutId == cubeInfo.layoutId;
  484. })
  485. const referenceModelPositionX = referenceModel.position.x * 100 - referenceModel.userData
  486. .modelWidth / 2 - parseFloat(cubeInfo.marginLeft);
  487. const wallPositionX = centerX - spaceWidth / 2 + (curSpace.spaceWallInfo.wallE ? 10 : 0) +
  488. parseFloat(cubeInfo.marginRight);
  489. const newModelWidth = Math.abs(referenceModelPositionX - wallPositionX);
  490. if (Math.abs(parseFloat(cubeInfo.rotation)) == 90) {
  491. scaleX = newModelWidth / modelWidth;
  492. } else {
  493. scaleY = newModelWidth / modelWidth;
  494. }
  495. positionX = wallPositionX + newModelWidth / 2;
  496. }
  497. if (cubeInfo.isStepAsideRight == 'true' && parseInt(cubeInfo.referenceModelLeft) > 0) {
  498. const referenceModel = this.gltfLayouts.find(item => {
  499. const layoutModelData = item.userData;
  500. return layoutModelData.id == parseInt(cubeInfo.referenceModelLeft) && layoutModelData
  501. .spaceId == cubeInfo.spaceId && layoutModelData.layoutId == cubeInfo.layoutId;
  502. })
  503. const referenceModelPositionX = referenceModel.position.x * 100 + referenceModel.userData
  504. .modelWidth / 2 + parseFloat(cubeInfo.marginLeft);
  505. const wallPositionX = centerX + spaceWidth / 2 - (curSpace.spaceWallInfo.wallE ? 10 : 0) -
  506. parseFloat(cubeInfo.marginRight);
  507. const newModelWidth = Math.abs(referenceModelPositionX - wallPositionX);
  508. if (Math.abs(parseFloat(cubeInfo.rotation)) == 90) {
  509. scaleX = newModelWidth / modelWidth;
  510. } else {
  511. scaleY = newModelWidth / modelWidth;
  512. }
  513. positionX = wallPositionX - newModelWidth / 2;
  514. // console.log("右边拉伸", Math.abs(parseFloat(cubeInfo.rotation)))
  515. }
  516. }
  517. // console.log("模型计算位置--", positionX, positionY)
  518. // console.log("模型计算位置", cubeInfo, centerX, centerY, spaceWidth, spaceHeight, modelWidth, modelHeight, spaceId, scaleX, scaleY, rotationY)
  519. let oldPosition = new THREE.Vector3();//当前几何体的位置参数
  520. oldPosition.copy(cube.position);
  521. cube.position.x = positionX / 100;
  522. cube.position.z = positionY / 100;
  523. cube.rotation.y = rotationY;
  524. cube.scale.x = scaleX ;
  525. cube.scale.z = scaleY;
  526. if (!cube.parent) { //说明还没添加到场景中-旧版方法
  527. this.scene.add(cube); //处理完毕后在加入场景中
  528. }
  529. if(scaleX>1 || scaleY>1){
  530. console.warn("***scaleinfo***",cubeInfo.id,scaleX,scaleY,cubeInfo.modelName)
  531. }
  532. // this.updateInfo(cube,oldPosition,scaleX,scaleY);//实例化方法
  533. },
  534. //更新家具模型到页面中
  535. updateInfo(cube,oldPosition,scaleX,scaleY){
  536. let lay = this.gltfLayouts.find(it=>it.uniId==cube.uniId);
  537. cube.instancedMeshIndexList.forEach(item=>{
  538. let index = item.instancedMeshIndex;
  539. let instancedMesh = this.instancedFurList[index];//网格实例对象
  540. let curMeshIndex = item.instancedAtIndex;//当前家具模型在网格实例对象里面的序号
  541. let stratMatrix = new THREE.Matrix4();//定义一个四维矩阵
  542. instancedMesh.getMatrixAt(curMeshIndex,stratMatrix);//获取当前几何体的四维矩阵到stratMatrix里面
  543. let scaleMatrix = new THREE.Matrix4(); //定义一个缩放变化矩阵
  544. let panMatrix = new THREE.Matrix4(); //定义一个平移变化矩阵
  545. if (!lay.loaded) { //说明还没添加到场景中
  546. scaleMatrix.makeScale(scaleX,1,scaleY); //获得缩放变化矩阵
  547. panMatrix.makeTranslation(cube.position.x,0,cube.position.z); //获得平移变化矩阵
  548. stratMatrix.multiply(scaleMatrix).premultiply(panMatrix);//通过矩阵计算获得最终的形变矩阵
  549. instancedMesh.instanceMatrix.needsUpdate = true;//更新之前,必须开启开关
  550. instancedMesh.setMatrixAt(curMeshIndex,stratMatrix);//更新几何体的世界矩阵
  551. this.scene.add(instancedMesh);
  552. }else{//更新形变矩阵
  553. panMatrix.makeTranslation(cube.position.x - oldPosition.x,0,cube.position.z - oldPosition.z); //获得平移变化矩阵
  554. stratMatrix.premultiply(panMatrix);//通过矩阵计算获得最终的形变矩阵
  555. instancedMesh.instanceMatrix.needsUpdate = true;//更新之前,必须开启开关
  556. instancedMesh.setMatrixAt(curMeshIndex,stratMatrix);//更新几何体的世界矩阵
  557. }
  558. })
  559. lay.loaded = true;
  560. },
  561. // 空间布局旋转镜像重置模型约束
  562. resetModelParameters(curSpace, cubeInfo) {
  563. // 旋转
  564. const defaultLayout = curSpace.layouts.find(item => {
  565. return item.isDefault
  566. })
  567. if (!defaultLayout) {
  568. return cubeInfo
  569. }
  570. let count = 0;
  571. switch (parseInt(defaultLayout.layoutRotate)) {
  572. case 90:
  573. count = 1;
  574. break;
  575. case 180:
  576. count = 2;
  577. break;
  578. case -90:
  579. count = 3;
  580. break;
  581. default:
  582. break;
  583. }
  584. for (let index = 0; index < count; index++) {
  585. let oldCubeInfo = JSON.parse(JSON.stringify(cubeInfo))
  586. oldCubeInfo.isStepAsideLeft = "false"
  587. oldCubeInfo.isStepAsideTop = "false"
  588. oldCubeInfo.isStepAsideRight = "false"
  589. oldCubeInfo.isStepAsideBottom = "false"
  590. oldCubeInfo.referenceModelLeft = "0"
  591. oldCubeInfo.referenceModelTop = "0"
  592. oldCubeInfo.referenceModelRight = "0"
  593. oldCubeInfo.referenceModelBottom = "0"
  594. oldCubeInfo.rotation = "0"
  595. oldCubeInfo.marginLeft = "0";
  596. oldCubeInfo.marginTop = "0";
  597. oldCubeInfo.marginRight = "0";
  598. oldCubeInfo.marginBottom = "0";
  599. // 是否靠墙
  600. if (cubeInfo.isStepAsideLeft == 'true') {
  601. oldCubeInfo.isStepAsideTop = 'true'
  602. }
  603. if (cubeInfo.isStepAsideTop == 'true') {
  604. oldCubeInfo.isStepAsideRight = 'true'
  605. }
  606. if (cubeInfo.isStepAsideRight == 'true') {
  607. oldCubeInfo.isStepAsideBottom = 'true'
  608. }
  609. if (cubeInfo.isStepAsideBottom == 'true') {
  610. oldCubeInfo.isStepAsideLeft = 'true'
  611. }
  612. // 参照物体
  613. if (parseInt(cubeInfo.referenceModelLeft) > 0) {
  614. oldCubeInfo.referenceModelTop = cubeInfo.referenceModelLeft;
  615. }
  616. if (parseInt(cubeInfo.referenceModelTop) > 0) {
  617. oldCubeInfo.referenceModelRight = cubeInfo.referenceModelTop;
  618. }
  619. if (parseInt(cubeInfo.referenceModelRight) > 0) {
  620. oldCubeInfo.referenceModelBottom = cubeInfo.referenceModelRight;
  621. }
  622. if (parseInt(cubeInfo.referenceModelBottom) > 0) {
  623. oldCubeInfo.referenceModelLeft = cubeInfo.referenceModelBottom;
  624. }
  625. // 边距
  626. oldCubeInfo.marginLeft = cubeInfo.marginTop;
  627. oldCubeInfo.marginTop = cubeInfo.marginRight;
  628. oldCubeInfo.marginRight = cubeInfo.marginBottom;
  629. oldCubeInfo.marginBottom = cubeInfo.marginLeft;
  630. oldCubeInfo.modelWidth = cubeInfo.modelHeight;
  631. oldCubeInfo.modelHeight = cubeInfo.modelWidth;
  632. // 旋转
  633. if (parseInt(cubeInfo.rotation) == 0 || parseInt(cubeInfo.rotation) == 90) {
  634. oldCubeInfo.rotation = parseInt(cubeInfo.rotation) + 90;
  635. }
  636. if (parseInt(cubeInfo.rotation) == 180) {
  637. oldCubeInfo.rotation = "-90";
  638. }
  639. if (parseInt(cubeInfo.rotation) == -90) {
  640. oldCubeInfo.rotation = "0";
  641. }
  642. // console.log("旋转前的模型参数X", cubeInfo, oldCubeInfo, defaultLayout)
  643. cubeInfo = oldCubeInfo;
  644. // console.log("旋转后的模型参数X", cubeInfo, oldCubeInfo, defaultLayout)
  645. }
  646. return cubeInfo;
  647. },
  648. }
  649. }