wallMethod.js 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  1. // const util = require('@/static/utils/util.js');
  2. // const config = require('@/static/config.js');
  3. import wallType from '@/static/wallData.js';
  4. // import requestConfig from '@/services/requestConfig.js';
  5. import * as THREE from 'three';
  6. import TWEEN from 'three/addons/libs/tween.module.js';
  7. export default {
  8. data() {
  9. return {
  10. // gltfUrl:"https://dm.static.elab-plus.com/3d/model/230519/floor01.glb",//模型地址
  11. // gltfName:"地板", //模型名称
  12. // gltfWidth:10, //模型宽度 10米
  13. // gltfHeight:10, //模型高度 10米
  14. }
  15. },
  16. watch: {},
  17. methods: {
  18. // modelItem 变化后的
  19. // wallObj 变化前的-一面墙下的某一段墙体
  20. drawModel(modelItem, spaceObj, wallObj, isAnimate=false){
  21. let that = this;
  22. //无变化则不需要启动动画
  23. if(modelItem.wallPositionX == wallObj.wallPositionX
  24. && modelItem.wallPositionY == wallObj.wallPositionY
  25. && modelItem.wallScaleX == wallObj.wallScaleX
  26. && modelItem.wallScaleY == wallObj.wallScaleY){
  27. return false;
  28. }
  29. let tx = wallObj.wallPositionX;
  30. let tz = wallObj.wallPositionY;
  31. let scaleX = wallObj.wallScaleX;
  32. let wallWidth = wallObj.wallWidth;//初始的墙体宽度-单位m
  33. //最终形变值
  34. let toPx = modelItem.wallPositionX;
  35. let toPz = modelItem.wallPositionY;
  36. let toScaleX = modelItem.wallScaleX;
  37. if(modelItem.wallType !=0 && parseFloat(modelItem.wallWidth) == 0){
  38. toScaleX = 0
  39. }
  40. if(isAnimate){//需要动画
  41. // console.log("墙体动画1----", tx, tz, scaleX,toPx, toPz, toScaleX,);
  42. // console.log("墙体动画2----", scaleX, toScaleX, wallObj.wallScaleX, wallObj);
  43. //初始形变值
  44. let spaceInitMatrix = [];//记录下动画创建时的初始变换矩阵
  45. wallObj.instancedMeshIndexList.forEach(item=>{
  46. let _index = item.instancedMeshIndex;
  47. let instancedMesh = this.instancedMeshList[_index];//获取网格实例
  48. let startMatrix = new THREE.Matrix4();//定义一个四维矩阵
  49. instancedMesh.getMatrixAt(item.instancedAtIndex,startMatrix);//获取当前几何体的四维矩阵到stratMatrix里面
  50. spaceInitMatrix.push({
  51. index:_index,
  52. matrix:startMatrix.clone(),
  53. })
  54. });
  55. var tween = new TWEEN.Tween({
  56. x: tx,
  57. z: tz,
  58. sx:scaleX,
  59. })
  60. .to({
  61. x: toPx,
  62. z: toPz,
  63. sx:toScaleX,
  64. }, 2000)
  65. .easing(TWEEN.Easing.Quadratic.InOut)
  66. .onUpdate((object)=> {
  67. wallObj.instancedMeshIndexList.forEach(item=>{
  68. let _index = item.instancedMeshIndex;
  69. let instancedMesh = this.instancedMeshList[_index];//获取网格实例
  70. let tmp = spaceInitMatrix.find(it=>it.index==_index);
  71. let stratMatrix = tmp.matrix.clone(); //获取初始变换矩阵
  72. // // 计算变化后的位置:位移后的位置 是 当前几何体的位置参数 加上 模型移动后的位置偏移量
  73. let moveX = object.x - tx;
  74. let moveZ = object.z - tz;
  75. let scaleMatrix = new THREE.Matrix4(); //定义一个缩放变化矩阵
  76. let panMatrix = new THREE.Matrix4(); //定义一个平移变化矩阵
  77. scaleMatrix.makeScale(object.sx / scaleX,1,1); //获得缩放变化矩阵
  78. panMatrix.makeTranslation(moveX,0,moveZ); //获得平移变化矩阵
  79. stratMatrix.multiply(scaleMatrix).premultiply(panMatrix);//通过矩阵计算获得最终的形变矩阵
  80. instancedMesh.instanceMatrix.needsUpdate = true;//更新之前,必须开启开关
  81. instancedMesh.setMatrixAt(item.instancedAtIndex,stratMatrix);//更新几何体的世界矩阵
  82. // console.warn("***drawModel-isAnimate0***",JSON.stringify(position),JSON.stringify(scale),wallObj.name,modelItem,wallObj);
  83. })
  84. }).onComplete(()=>{
  85. this.tweenCameraAnmaChange(false);
  86. let gltfWall = this.gltfWalls.find(gltfWall=>gltfWall.uniId==wallObj.uniId);//判断是否已经添加过
  87. if(gltfWall){
  88. gltfWall.wallPositionX = modelItem.wallPositionX;
  89. gltfWall.wallPositionY = modelItem.wallPositionY;
  90. gltfWall.wallScaleX = modelItem.wallScaleX;
  91. gltfWall.wallScaleY = modelItem.wallScaleY;
  92. gltfWall.wallRotateY = modelItem.wallRotateY;
  93. gltfWall.wallWidth = modelItem.wallWidth;
  94. }else{
  95. console.warn("***changeSpacesAnim-over-wall***", wallObj.uniId,wallObj)
  96. }
  97. // console.warn("***changeSpacesAnim-over-wall***", modelItem)
  98. });
  99. // 开始动画
  100. tween.start();
  101. this.tweenCameraAnmaChange(true)
  102. }else{
  103. // console.log("墙体变化", modelItem, wallObj, wallObj.wallWidth);
  104. wallObj.instancedMeshIndexList.forEach(item=>{
  105. let _index = item.instancedMeshIndex;
  106. let instancedMesh = this.instancedMeshList[_index];//获取网格实例
  107. // let tmp = spaceInitMatrix.find(it=>it.index==_index);
  108. // let stratMatrix = tmp.matrix.clone(); //获取初始变换矩阵
  109. let stratMatrix = new THREE.Matrix4();//定义一个四维矩阵
  110. instancedMesh.getMatrixAt(item.instancedAtIndex,stratMatrix);//获取当前几何体的四维矩阵到stratMatrix里面
  111. // // 计算变化后的位置:位移后的位置 是 当前几何体的位置参数 加上 模型移动后的位置偏移量
  112. let moveX = toPx - tx;
  113. let moveZ = toPz - tz;
  114. let scaleMatrix = new THREE.Matrix4(); //定义一个缩放变化矩阵
  115. let panMatrix = new THREE.Matrix4(); //定义一个平移变化矩阵
  116. scaleMatrix.makeScale(toScaleX / scaleX,1,1); //获得缩放变化矩阵
  117. panMatrix.makeTranslation(moveX,0,moveZ); //获得平移变化矩阵
  118. stratMatrix.multiply(scaleMatrix).premultiply(panMatrix);//通过矩阵计算获得最终的形变矩阵
  119. instancedMesh.instanceMatrix.needsUpdate = true;//更新之前,必须开启开关
  120. instancedMesh.setMatrixAt(item.instancedAtIndex,stratMatrix);//更新几何体的世界矩阵
  121. // console.warn("***drawModel-isAnimate0***",JSON.stringify(position),JSON.stringify(scale),wallObj.name,modelItem,wallObj);
  122. })
  123. let gltfWall = this.gltfWalls.find(gltfWall=>gltfWall.uniId==wallObj.uniId);//判断是否已经添加过
  124. gltfWall.wallPositionX = modelItem.wallPositionX;
  125. gltfWall.wallPositionY = modelItem.wallPositionY;
  126. gltfWall.wallScaleX = modelItem.wallScaleX;
  127. gltfWall.wallScaleY = modelItem.wallScaleY;
  128. gltfWall.wallRotateY = modelItem.wallRotateY;
  129. gltfWall.wallWidth = modelItem.wallWidth;
  130. gltfWall.lastWallType = 50;
  131. }
  132. },
  133. //预处理需要加载墙体模型的数据-减少模型请求数
  134. preWallData(wallArr){
  135. let realWallArr = [];
  136. wallArr && wallArr.forEach((item, index) => {
  137. item.uniId = Date.now() + index;//唯一标识
  138. //获取墙体对应的gltb模型的相关信息
  139. let modelTypeItem = wallType.find(it=>it.type == item.wallModelData.wallType) //wallType[item.wallModelData.wallType];
  140. // console.log("取墙体对应的gltb模型的相关信息", modelTypeItem, item);
  141. let object = realWallArr.find(it=>it.index==item.wallModelData.wallType);
  142. //列表中还没有这个数据
  143. if(!object){
  144. let it = {
  145. url:modelTypeItem.url,
  146. list:[item],
  147. name:modelTypeItem.name,
  148. index:item.wallModelData.wallType,//在模型当中的类型编码
  149. }
  150. realWallArr.push(it)
  151. }else{
  152. object.list.push(item);
  153. }
  154. });
  155. return realWallArr;
  156. },
  157. // 加载墙体模型
  158. loadWallModels(realData, wallList, arrLength,resolve){
  159. var that = this;
  160. if(!realData.url){
  161. console.warn("***模型wallType不存在***",realData);
  162. return false;
  163. }
  164. that.loader.load(realData.url, ( gltf ) => {
  165. that.progress = parseInt(100/arrLength) + that.progress;
  166. if(that.progress>100){
  167. that.progress = 100;
  168. }
  169. this.$store.state.loadingMsg="加载中..." + that.progress+'%';
  170. // console.log("模型加载成功",that.progress,realData,gltf);
  171. // 第一个方案:递归获取模型-并一一实例化,减少渲染次数,提高性能;因为实例化了几何体复用了geometry 和 material
  172. // DrawCall和内存都很低
  173. gltf.scene.traverse((child)=> {
  174. if (child.isMesh && child.visible) {
  175. let instancedMesh = new THREE.InstancedMesh(child.geometry.clone(), child.material.clone(), realData.list.length);
  176. this.instancedMeshList.push(instancedMesh);
  177. //realData 该模型被重复使用时的每一次的形变参数等
  178. realData.list && realData.list.forEach((it,i)=>{
  179. let modelItem = JSON.parse(JSON.stringify(it.wallModelData));
  180. gltf.scene.position.set(modelItem.wallPositionX, 0, modelItem.wallPositionY);
  181. gltf.scene.scale.set(modelItem.wallScaleX, 1, modelItem.wallScaleY);
  182. gltf.scene.rotation.y = modelItem.wallRotateY;
  183. gltf.scene.updateMatrixWorld();//更新世界坐标-这样,子模型也同步更新了
  184. instancedMesh.setMatrixAt(i, child.matrixWorld);
  185. instancedMesh.instanceMatrix.needsUpdate = true;
  186. // instancedMesh.setColorAt(i, child.material.color);
  187. // instancedMesh.instanceColor.needsUpdate = true;
  188. // console.log("***matrixWorld***",child.matrixWorld);
  189. let gltfWall = that.gltfWalls.find(gltfWall=>gltfWall.uniId==it.uniId);//判断是否已经添加过
  190. if(!gltfWall){
  191. let md = {
  192. uniId:it.uniId,//模型实例的唯一标识
  193. spaceId:it.spaceId,
  194. instancedMeshIndexList:[//标识网格实例数组的序号 以及 当前几何体 在网格实例的序号
  195. {instancedMeshIndex:this.instancedMeshList.length-1,instancedAtIndex:i},
  196. ],
  197. // id:child.id,//几何体的id
  198. // name:child.name,//几何体的id
  199. wallPositionX:modelItem.wallPositionX,
  200. wallPositionY:modelItem.wallPositionY,
  201. wallScaleX:modelItem.wallScaleX,
  202. wallScaleY:modelItem.wallScaleY,
  203. wallRotateY:modelItem.wallRotateY,
  204. wallWidth:modelItem.wallWidth,
  205. // lastWallType:51,
  206. wallModelData:modelItem,
  207. wallModelInitData:modelItem, // 保留初始化墙体数据,方便空间变形计算缩放比例
  208. wallDirection:it.wallDirection,
  209. willCurWallType: -1, // 即将成为当前模型,作用于动画加载完替换
  210. lastWallType: -1 // 上一次墙体模型
  211. };
  212. that.gltfWalls.push(md);
  213. }else{
  214. gltfWall.instancedMeshIndexList.push({
  215. instancedMeshIndex:this.instancedMeshList.length-1,instancedAtIndex:i
  216. })
  217. }
  218. })
  219. instancedMesh.userType = "mesh";
  220. // instancedMesh.receiveShadow = true;//材质是否接收阴影
  221. that.scene.add(instancedMesh);
  222. }
  223. });
  224. resolve();
  225. });
  226. },
  227. //计算墙体对应位置和形变参数-提前计算
  228. computeWallHandleOld(spaceObj,wallObj){
  229. // let cube = wallObj.obj;
  230. let list = wallObj.wallData;//墙体列表
  231. let scale = 100;
  232. let spaceWallInfo = {wallN:false, wallS:false, wallW:false, wallE:false};
  233. spaceObj.spaceWallInfo = spaceWallInfo;
  234. list.forEach((item)=>{//空间下的四面墙壁
  235. let lastWallPosition = 0;
  236. let wallDirection = item.wallDirection;
  237. item.wallModelData.forEach((modelItem,index)=>{//每个墙壁下的位置计算
  238. // 默认空间中心点
  239. let wallPositionX = spaceObj.centerX / 100;
  240. let wallPositionY = spaceObj.centerY / 100;
  241. let wallRotateY = 0;
  242. let wallHeight = 10;//item.wallHeight // 墙体厚度模型10cm
  243. if(wallDirection=="N"){
  244. wallPositionY = wallPositionY *-1 - spaceObj.spaceHeight / 2 / scale;
  245. let wallHeight2 = wallHeight / 2 / scale;
  246. wallPositionY = wallPositionY + wallHeight2;
  247. spaceWallInfo.wallN = true;
  248. }
  249. else if(wallDirection=="S"){
  250. wallPositionY = wallPositionY *-1 + spaceObj.spaceHeight / 2 / scale;
  251. let wallHeight2 = wallHeight / 2 / scale;
  252. wallPositionY = wallPositionY - wallHeight2;
  253. spaceWallInfo.wallS = true;
  254. }
  255. if(wallDirection=="E"){
  256. // console.log("模型参数", wallPositionX, spaceObj.spaceWidth)
  257. wallPositionY = wallPositionY * -1;
  258. wallPositionX = wallPositionX + spaceObj.spaceWidth / 2 / scale;
  259. let wallHeight2 = wallHeight / 2 / scale;
  260. wallPositionX = wallPositionX - wallHeight2; // 减去墙体本身的厚度
  261. wallRotateY = Math.PI/2; // 东西墙 模型旋转90度
  262. spaceWallInfo.wallE = true;
  263. }else if(wallDirection=="W"){
  264. wallPositionY = wallPositionY *-1;
  265. wallPositionX = wallPositionX - spaceObj.spaceWidth / 2 / scale;
  266. let wallHeight2 = wallHeight / 2 / scale;
  267. wallPositionX = wallPositionX + wallHeight2; // 减去墙体本身的厚度
  268. wallRotateY = Math.PI/2; // 东西墙 模型旋转90度
  269. spaceWallInfo.wallW = true;
  270. }
  271. let wallScaleX = 1;
  272. let wallScaleY = 1;
  273. let modelWidth = 10;
  274. if(modelItem.wallType == '7') {
  275. modelWidth = 150
  276. }else if(modelItem.wallType == '21'){
  277. modelWidth = 100
  278. }else if(modelItem.wallType == '22'){
  279. modelWidth = 200
  280. }else if(modelItem.wallType == '23'){
  281. modelWidth = 300
  282. }else if(modelItem.wallType == '24'){
  283. modelWidth = 400
  284. }else if(modelItem.wallType == '25'){
  285. modelWidth = 500
  286. }else if(modelItem.wallType == '26'){
  287. modelWidth = 600
  288. }
  289. let tmdWidth = modelItem.wallWidth;//记录
  290. // console.log("XXXXXXXXXXXXXXXX", modelWidth, spaceObj)
  291. // 计算墙体的 X Y W H
  292. //说明该面墙壁只使用了一个模型-独占形式
  293. if(modelItem.isStepAsideTopRight == 'true' && modelItem.isStepAsideBottomLeft == 'true'){
  294. if(wallDirection=="S" || wallDirection=="N"){//南北
  295. wallScaleX = spaceObj.spaceWidth / modelWidth;
  296. }else{//东西
  297. wallScaleX = spaceObj.spaceHeight / modelWidth;
  298. }
  299. if((parseInt(modelItem.wallType) >=21 && parseInt(modelItem.wallType) <=26) || parseInt(modelItem.wallType)== 7){
  300. }else{
  301. modelItem.wallWidth = wallScaleX * modelWidth; // 解决模型行拉伸定位问题, 先注释
  302. }
  303. }else{//墙面是多端墙体组合而成的
  304. if(modelItem.isFixedWidth == 'true'){//该墙体锁定宽度-即不可缩放
  305. let wallWidth = modelItem.wallWidth; // 墙体宽度
  306. // console.log("模型的尺寸",wallWidth, spaceObj.spaceWidth, spaceObj.centerX)
  307. //起始墙体-南北从左侧算,东西则从上侧计算
  308. if(modelItem.isStepAsideBottomLeft == 'true' || modelItem.isStepAsideTopRight == 'true'){
  309. if(wallDirection=="S" || wallDirection=="N"){//南北
  310. wallPositionX = spaceObj.centerX - (spaceObj.spaceWidth - wallWidth) / 2;
  311. wallPositionX = wallPositionX / scale; // 转换成m
  312. }else{
  313. wallPositionY = -spaceObj.centerY - (spaceObj.spaceHeight - wallWidth) / 2;
  314. wallPositionY = wallPositionY / scale; // 转换成m
  315. }
  316. }else{
  317. if(wallDirection=="S" || wallDirection=="N"){//南北
  318. wallPositionX = lastWallPosition + (wallWidth / 2 / scale);
  319. }else{
  320. wallPositionY = lastWallPosition + (wallWidth / 2 / scale);
  321. }
  322. }
  323. // console.log("模型的尺寸",wallWidth, wallPositionX)
  324. if(modelItem.wallType == 0){
  325. wallScaleX = modelItem.wallWidth / wallHeight;
  326. }
  327. //计算当前墙体占据的整面墙体的大小-方便下一段墙体的计算
  328. if(wallDirection=="S" || wallDirection=="N"){//南北
  329. lastWallPosition = wallPositionX + wallWidth / 2 / scale;
  330. }else{
  331. lastWallPosition = wallPositionY + wallWidth / 2 / scale;
  332. }
  333. }else{//可变墙体-UE编辑器通常把它放到最后一段墙体
  334. let wallWidth = 0;
  335. //墙体的宽度是计算得出的
  336. if(wallDirection=="S" || wallDirection=="N"){//南北
  337. wallWidth = (spaceObj.centerX + spaceObj.spaceWidth / 2) - lastWallPosition * scale; // 墙体宽度
  338. // console.log("最后一个模型",spaceObj.centerX, spaceObj.spaceWidth / 2, lastWallPosition)
  339. }else{
  340. wallWidth = (-spaceObj.centerY + spaceObj.spaceHeight / 2) - lastWallPosition * scale; // 墙体宽度
  341. }
  342. wallWidth = wallWidth / scale; // cm转换成m
  343. if(modelItem.wallType == 0){
  344. wallScaleX = wallWidth * wallHeight;
  345. if(wallDirection=="S" || wallDirection=="N"){//南北
  346. wallPositionX = lastWallPosition + wallWidth / 2;
  347. }else{
  348. wallPositionY = lastWallPosition + wallWidth / 2;
  349. }
  350. }
  351. modelItem.wallWidth = wallWidth*scale;//确保单位一致
  352. }
  353. }
  354. //计算得出墙体相应的位置和变形属性
  355. modelItem.wallPositionX = wallPositionX;
  356. modelItem.wallPositionY = wallPositionY;
  357. modelItem.wallScaleX = wallScaleX;
  358. modelItem.wallScaleY = wallScaleY;
  359. modelItem.wallRotateY = wallRotateY;
  360. // console.log("XXXXXXXXXXXXXXXX", modelWidth, modelItem)
  361. //新版下,符合条件的不止一个了,因为新版下是以模型里面的几何体为单元,个数较多
  362. this.gltfWalls.forEach(gltfItem=>{
  363. if(gltfItem.spaceId == spaceObj.spaceId
  364. && wallDirection == gltfItem.wallDirection
  365. && modelItem.id == gltfItem.wallModelData.id){
  366. gltfItem.wallModelData = JSON.parse(JSON.stringify(modelItem));
  367. }
  368. })
  369. })
  370. spaceObj.spaceWallInfo = spaceWallInfo;
  371. })
  372. },
  373. // 新计算墙体逻辑
  374. computeWallHandle(oldSpaceObj, spaceObj, wallObj, moveOut, direction){
  375. var that = this;
  376. let list = wallObj.wallData;//墙体列表
  377. let scale = 100;
  378. console.log("墙体数据1",direction, list, moveOut, that.gltfWalls, wallObj);
  379. console.log("旧空间+++", oldSpaceObj.spaceId, oldSpaceObj.centerX, oldSpaceObj.centerY,oldSpaceObj.spaceWidth, oldSpaceObj.spaceHeight);
  380. console.log("新空间+++", spaceObj.spaceId, spaceObj.centerX, spaceObj.centerY,spaceObj.spaceWidth, spaceObj.spaceHeight);
  381. list.forEach((item)=>{//空间下的四面墙壁
  382. let lastWallPosition = 0;
  383. let wallDirection = item.wallDirection;
  384. let spaceSize = 0
  385. let oldSpaceSize = 0
  386. let minWallWidth = 10; // 实墙最小宽度
  387. let wallCount = item.wallModelData.length;
  388. let isCurWall = true;
  389. let isCreateNewWall = false;
  390. let newWallType = null;
  391. if(wallDirection=="N" || wallDirection=="S"){
  392. spaceSize = spaceObj.spaceWidth;
  393. oldSpaceSize = oldSpaceObj.spaceWidth;
  394. }else{
  395. spaceSize = spaceObj.spaceHeight;
  396. oldSpaceSize = oldSpaceObj.spaceHeight;
  397. }
  398. let isComputeWall = true;
  399. if((direction=="S" || direction=="N") && (wallDirection == "S" || wallDirection == "N")){
  400. isComputeWall = false;
  401. }
  402. if((direction=="E" || direction=="W") && (wallDirection == "E" || wallDirection == "W")){
  403. isComputeWall = false;
  404. }
  405. if(wallCount > 2 && isComputeWall){ // 墙体个数,判断是否有墙体模型
  406. const modelItem0 = item.wallModelData[0]; // 固定尺寸实体墙
  407. const modelItem1 = item.wallModelData[1]; // 取出模型的宽度
  408. const modelItem2 = item.wallModelData[2]; // 伸缩实体墙
  409. const leftWallChangeValue = spaceSize - minWallWidth - parseFloat(modelItem1.wallWidth) - parseFloat(modelItem0.wallWidth);
  410. console.log("当前模型的类型信息", modelItem1, leftWallChangeValue)
  411. if(moveOut){ // 放大
  412. // 1.判断是否是从无到有
  413. // 是
  414. // 2 先还原窗户,找到最合适的窗户
  415. // 3 最后还原第一面实体墙
  416. // 否
  417. // 4 找到最合适的窗户
  418. // 5 最后还原第一面实体墙
  419. const curWallType = wallType.find(it=>it.type == modelItem1.wallType)
  420. const wallTypeGroups = wallType.filter(it=>it.group == curWallType.group)
  421. const wallWidth = spaceSize - 2 * minWallWidth;
  422. if(wallWidth > curWallType.width){
  423. newWallType = curWallType;
  424. }
  425. for (let index = 0; index < wallTypeGroups.length; index++) {
  426. const element = wallTypeGroups[index];
  427. if(!newWallType){
  428. if(element.width <= wallWidth){
  429. newWallType = element;
  430. }
  431. }else{
  432. if(element.width <= wallWidth && newWallType.width <= element.width ){
  433. newWallType = element;
  434. }
  435. }
  436. console.log("寻找最大的窗户",index, wallWidth, newWallType, element.width)
  437. }
  438. item.wallModelData[1].wallWidth = newWallType.width;
  439. if(newWallType != curWallType){ // 新模型
  440. item.wallModelData[1].willCurWallType = newWallType.type;
  441. item.wallModelData[1].lastWallType = curWallType.type;
  442. isCreateNewWall = true;
  443. }else{
  444. console.log("还原老模型")
  445. }
  446. // 初始化模型的尺寸
  447. const initWallModel = this.gltfWalls.find(it=>{
  448. return it.spaceId == spaceObj.spaceId && it.wallDirection == wallDirection && it.wallModelData.wallType == 0 && it.wallModelData.isFixedWidth == 'true'
  449. })
  450. const item0Width = Math.min((spaceSize - newWallType.width - minWallWidth), initWallModel.wallModelInitData.wallWidth);
  451. item.wallModelData[0].wallWidth = item0Width
  452. console.log("还原第一面墙的宽度", item0Width ,spaceSize, newWallType.width, minWallWidth);
  453. }else{ // 缩小
  454. // 初始化模型的尺寸
  455. const initWallModel = this.gltfWalls.find(it=>{
  456. return it.spaceId == spaceObj.spaceId && it.wallDirection == wallDirection && it.wallModelData.wallType == 0 && it.wallModelData.isFixedWidth == 'true'
  457. })
  458. const firstWallW = initWallModel.wallModelInitData.wallWidth;
  459. // 计算最右边墙体尺寸
  460. const modelItem2W = oldSpaceSize - parseFloat(firstWallW) - parseFloat(modelItem1.wallWidth);
  461. if(modelItem2W > 10){
  462. }
  463. // 计算最右边墙体的比例
  464. const modelItem0Scale = firstWallW / oldSpaceSize;
  465. const modelItem2Scale = modelItem2W / oldSpaceSize;
  466. const modelItem0NewW = modelItem0Scale * spaceSize;
  467. const modelItem2NewW = modelItem2Scale * spaceSize;
  468. console.log("墙体模型比例数据", oldSpaceSize,spaceSize, initWallModel.wallModelInitData.wallWidth,modelItem0Scale, modelItem0NewW, modelItem2NewW);
  469. if(leftWallChangeValue < 0){
  470. const newWallWidth = Math.max(parseFloat(modelItem0.wallWidth) + leftWallChangeValue, minWallWidth);
  471. item.wallModelData[0].wallWidth = Math.floor(newWallWidth)
  472. console.log("缩放左边实体墙",spaceObj.spaceId, newWallWidth, leftWallChangeValue);
  473. if(modelItem1.wallWidth > spaceSize - 2 * minWallWidth){
  474. console.log("无法放置墙体模型", newWallWidth, leftWallChangeValue);
  475. // 寻找合适的模型
  476. const curWallType = wallType.find(it=>it.type == modelItem1.wallType)
  477. // 可显示的最大模型
  478. if(curWallType){
  479. const wallTypeGroups = wallType.filter(it=>it.group == curWallType.group)
  480. const wallWidth = spaceSize - 2 * minWallWidth;
  481. for (let index = 0; index < wallTypeGroups.length; index++) {
  482. const element = wallTypeGroups[index];
  483. if(!newWallType){
  484. if(element.width <= wallWidth && element.width <= curWallType.width){
  485. newWallType = element;
  486. }
  487. }else{
  488. if(newWallType.width <= element.width && element.width <= wallWidth && element.width <= curWallType.width){
  489. newWallType = element;
  490. }
  491. }
  492. }
  493. console.log("是否需要替换墙体模型",spaceObj.spaceHeight, wallDirection, newWallType, curWallType.type)
  494. if(newWallType){
  495. if(curWallType.type != newWallType.type){
  496. console.log("最合适的墙体模型", spaceObj.spaceId, wallWidth, direction, wallDirection)
  497. item.wallModelData[1].wallWidth = newWallType.width;
  498. item.wallModelData[1].willCurWallType = newWallType.type;
  499. item.wallModelData[1].lastWallType = curWallType.type;
  500. item.wallModelData[0].wallWidth = Math.floor((spaceSize - newWallType.width) / 2)
  501. isCurWall = false;
  502. // 添加新模型
  503. const index = this.gltfWalls.findIndex(it=>{
  504. // console.log("最合适的墙体模型", it.spaceId, spaceObj.spaceId, it.wallDirection, wallDirection, newWallType.wallType, it.wallModelData.wallType)
  505. return it.spaceId == spaceObj.spaceId && it.wallDirection == wallDirection && newWallType.wallType == it.wallModelData.wallType
  506. })
  507. if(index!=-1){
  508. console.log("不需要加载新模型", spaceObj.spaceId, direction, wallDirection)
  509. isCreateNewWall = false;
  510. }else{
  511. console.log("需要加载新模型", index)
  512. isCreateNewWall = true;
  513. }
  514. }else{
  515. console.log("保持当前模型的尺寸", spaceObj.spaceHeight, direction, wallDirection)
  516. item.wallModelData[1].wallWidth = 0.0001;
  517. item.wallModelData[1].willCurWallType = -1;
  518. }
  519. }else{
  520. console.log("没有合适的模型替换", spaceObj.spaceId, direction, wallDirection)
  521. item.wallModelData[1].wallWidth = 0.0001;
  522. item.wallModelData[1].willCurWallType = -1;
  523. }
  524. }
  525. }else{
  526. console.log("不需要添加");
  527. }
  528. }else{
  529. item.wallModelData[0].wallWidth = Math.floor(modelItem0NewW)
  530. console.log("等比缩放");
  531. }
  532. }
  533. }else{
  534. console.log("没有缩放墙体")
  535. }
  536. // 判断是否有下一级
  537. if((direction=="S" && wallDirection !="S") || (direction =="W" && wallDirection !="W")){ // 处理不同面的墙体,
  538. item.wallModelData.forEach((modelItem,index)=>{//每个墙壁下的位置计算
  539. // 默认空间中心点
  540. let wallPositionX = spaceObj.centerX / 100;
  541. let wallPositionY = spaceObj.centerY / 100;
  542. let wallRotateY = 0;
  543. let wallHeight = 10;//item.wallHeight // 墙体厚度模型10cm
  544. if(wallDirection=="N"){
  545. wallPositionY = wallPositionY *-1 - spaceObj.spaceHeight / 2 / scale;
  546. let wallHeight2 = wallHeight / 2 / scale;
  547. wallPositionY = wallPositionY + wallHeight2;
  548. }
  549. else if(wallDirection=="S"){
  550. wallPositionY = wallPositionY *-1 + spaceObj.spaceHeight / 2 / scale;
  551. let wallHeight2 = wallHeight / 2 / scale;
  552. wallPositionY = wallPositionY - wallHeight2;
  553. }
  554. if(wallDirection=="E"){
  555. // console.log("模型参数", wallPositionX, spaceObj.spaceWidth)
  556. wallPositionY = wallPositionY * -1;
  557. wallPositionX = wallPositionX + spaceObj.spaceWidth / 2 / scale;
  558. let wallHeight2 = wallHeight / 2 / scale;
  559. wallPositionX = wallPositionX - wallHeight2; // 减去墙体本身的厚度
  560. wallRotateY = Math.PI/2; // 东西墙 模型旋转90度
  561. }else if(wallDirection=="W"){
  562. wallPositionY = wallPositionY *-1;
  563. wallPositionX = wallPositionX - spaceObj.spaceWidth / 2 / scale;
  564. let wallHeight2 = wallHeight / 2 / scale;
  565. wallPositionX = wallPositionX + wallHeight2; // 减去墙体本身的厚度
  566. wallRotateY = Math.PI/2; // 东西墙 模型旋转90度
  567. }
  568. let wallScaleX = modelItem.wallScaleX;
  569. let wallScaleY = 1;
  570. let modelWidth = 10;
  571. if(modelItem.wallType == '7') {
  572. modelWidth = 150
  573. }else if(modelItem.wallType == '21'){
  574. modelWidth = 100
  575. }else if(modelItem.wallType == '22'){
  576. modelWidth = 200
  577. }else if(modelItem.wallType == '23'){
  578. modelWidth = 300
  579. }else if(modelItem.wallType == '24'){
  580. modelWidth = 400
  581. }else if(modelItem.wallType == '25'){
  582. modelWidth = 500
  583. }else if(modelItem.wallType == '26'){
  584. modelWidth = 600
  585. }
  586. let tmdWidth = modelItem.wallWidth;//记录
  587. // console.log("XXXXXXXXXXXXXXXX", modelWidth, spaceObj)
  588. let wallWidth = 0; // 墙体宽度
  589. // 计算墙体的 X Y W H
  590. //说明该面墙壁只使用了一个模型-独占形式
  591. if(modelItem.isStepAsideTopRight == 'true' && modelItem.isStepAsideBottomLeft == 'true'){
  592. if(wallDirection=="S" || wallDirection=="N"){//南北
  593. wallScaleX = spaceObj.spaceWidth / modelWidth;
  594. }else{//东西
  595. wallScaleX = spaceObj.spaceHeight / modelWidth;
  596. }
  597. if((parseInt(modelItem.wallType) >=21 && parseInt(modelItem.wallType) <=26) || parseInt(modelItem.wallType)== 7){
  598. }else{
  599. modelItem.wallWidth = wallScaleX * modelWidth; // 解决模型行拉伸定位问题, 先注释
  600. }
  601. }else{//墙面是多端墙体组合而成的
  602. if(modelItem.isFixedWidth == 'true'){//该墙体锁定宽度-即不可缩放
  603. wallWidth = modelItem.wallWidth; // 墙体宽度
  604. // console.log("模型的尺寸",wallWidth, spaceObj.spaceWidth, spaceObj.centerX)
  605. //起始墙体-南北从左侧算,东西则从上侧计算
  606. if(modelItem.isStepAsideBottomLeft == 'true' || modelItem.isStepAsideTopRight == 'true'){
  607. if(wallDirection=="S" || wallDirection=="N"){//南北
  608. wallPositionX = spaceObj.centerX - (spaceObj.spaceWidth - wallWidth) / 2;
  609. wallPositionX = wallPositionX / scale; // 转换成m
  610. }else{
  611. wallPositionY = -spaceObj.centerY - (spaceObj.spaceHeight - wallWidth) / 2;
  612. wallPositionY = wallPositionY / scale; // 转换成m
  613. }
  614. }else{
  615. if(wallDirection=="S" || wallDirection=="N"){//南北
  616. wallPositionX = lastWallPosition + (wallWidth / 2 / scale);
  617. }else{
  618. wallPositionY = lastWallPosition + (wallWidth / 2 / scale);
  619. }
  620. }
  621. // console.log("模型的尺寸",wallWidth, wallPositionX)
  622. if(modelItem.wallType == 0){
  623. wallScaleX = modelItem.wallWidth / wallHeight;
  624. }else{
  625. console.log("墙体模型的缩放", spaceObj.spaceId,wallDirection, modelItem);
  626. // if(!moveOut){
  627. const curWallType = wallType.find(it=>it.type == modelItem.wallType)
  628. wallScaleX = modelItem.wallWidth / curWallType.width;
  629. console.log("墙体模型的缩小", modelItem,direction,wallDirection);
  630. // }else{
  631. // console.log("墙体模型的放大", wallScaleX);
  632. // }
  633. }
  634. //计算当前墙体占据的整面墙体的大小-方便下一段墙体的计算
  635. if(wallDirection=="S" || wallDirection=="N"){//南北
  636. lastWallPosition = wallPositionX + wallWidth / 2 / scale;
  637. }else{
  638. lastWallPosition = wallPositionY + wallWidth / 2 / scale;
  639. }
  640. // wallPositionY = 1;
  641. }else{//可变墙体-UE编辑器通常把它放到最后一段墙体
  642. wallWidth = 0;
  643. //墙体的宽度是计算得出的
  644. if(wallDirection=="S" || wallDirection=="N"){//南北
  645. wallWidth = (spaceObj.centerX + spaceObj.spaceWidth / 2) - lastWallPosition * scale; // 墙体宽度
  646. // console.log("最后一个模型",spaceObj.centerX, spaceObj.spaceWidth / 2, lastWallPosition)
  647. }else{
  648. wallWidth = (-spaceObj.centerY + spaceObj.spaceHeight / 2) - lastWallPosition * scale; // 墙体宽度
  649. }
  650. wallWidth = wallWidth / scale; // cm转换成m
  651. if(modelItem.wallType == 0){
  652. wallScaleX = wallWidth * wallHeight;
  653. if(wallDirection=="S" || wallDirection=="N"){//南北
  654. wallPositionX = lastWallPosition + wallWidth / 2;
  655. }else{
  656. wallPositionY = lastWallPosition + wallWidth / 2;
  657. }
  658. }
  659. modelItem.wallWidth = wallWidth*scale;//确保单位一致
  660. // wallPositionY = 1;
  661. }
  662. }
  663. console.log("移动墙体模型-空间信息", spaceObj.spaceWidth, spaceObj.centerX, spaceObj.centerY, spaceObj)
  664. console.log("移动墙体模型-墙体信息",spaceObj.spaceId,direction, wallDirection, modelItem.wallType, wallWidth, this.wallList)
  665. //计算得出墙体相应的位置和变形属性
  666. modelItem.wallPositionX = wallPositionX;
  667. modelItem.wallPositionY = wallPositionY;
  668. modelItem.wallScaleX = wallScaleX;
  669. modelItem.wallScaleY = wallScaleY;
  670. modelItem.wallRotateY = wallRotateY;
  671. modelItem.wallWidth = wallWidth;
  672. if(modelItem.wallType == 2){
  673. console.log("移动墙体模型-空间信息1", modelItem, this.gltfWalls)
  674. }
  675. // 更新数据
  676. if(isComputeWall || direction == wallDirection){
  677. this.gltfWalls.forEach(gltfItem=>{
  678. if(gltfItem.spaceId == spaceObj.spaceId && wallDirection == gltfItem.wallDirection && modelItem.id == gltfItem.wallModelData.id ){
  679. gltfItem.wallModelData = JSON.parse(JSON.stringify(modelItem));
  680. gltfItem.willCurWallType = modelItem.willCurWallType
  681. console.log("墙体更新", gltfItem.willCurWallType, direction)
  682. if(gltfItem.wallModelData.wallType != 0){
  683. gltfItem.isDidWall = isCreateNewWall;
  684. }
  685. }
  686. })
  687. }
  688. if(modelItem.wallType == 2){
  689. console.log("移动墙体模型-墙体信息1++++++++",spaceObj.spaceId, direction, wallDirection, isComputeWall, modelItem,this.gltfWalls)
  690. }
  691. //数据更新到wallList中,确保数据一致性
  692. this.wallList.forEach(wallItem=>{
  693. const walls = JSON.parse(wallItem.wallJson);
  694. // console.log("墙体数据2----------", walls, modelItem);
  695. walls.wallData.forEach(wall=>{
  696. wall.wallModelData.forEach(wallmodel=>{
  697. //从wallList找到这段墙体
  698. if(wall.wallDirection == wallDirection && wallmodel.id == modelItem.id && walls.spaceId == spaceObj.spaceId){
  699. if(wallmodel.wallType == 0 && wallmodel.isFixedWidth == 'true'){
  700. wallmodel.wallWidth = modelItem.wallWidth;
  701. console.log("墙体数据31----实体墙------",spaceObj.spaceId, modelItem.wallWidth, modelItem);
  702. }
  703. if(wallmodel.wallType != 0){
  704. wallmodel.wallWidth = modelItem.wallWidth;
  705. const curWallType = wallType.find(it=>it.type == modelItem.willCurWallType)
  706. if(curWallType){
  707. wallmodel.wallType = curWallType.type;
  708. }
  709. }
  710. }
  711. })
  712. })
  713. wallItem.wallJson = JSON.stringify(walls);
  714. })
  715. if(modelItem.wallType == 2){
  716. console.log("移动墙体模型-墙体信息2++++++++",spaceObj.spaceId, direction, wallDirection, isComputeWall, modelItem,this.wallList)
  717. }
  718. })
  719. }else{
  720. console.log("同面墙体只移动位置", direction, wallDirection)
  721. item.wallModelData.forEach((modelItem,index)=>{//每个墙壁下的位置计算
  722. // 默认空间中心点
  723. let wallPositionX = spaceObj.centerX / 100;
  724. let wallPositionY = spaceObj.centerY / 100;
  725. let wallRotateY = 0;
  726. let wallHeight = 10;//item.wallHeight // 墙体厚度模型10cm
  727. if(wallDirection=="N"){
  728. wallPositionY = wallPositionY *-1 - spaceObj.spaceHeight / 2 / scale;
  729. let wallHeight2 = wallHeight / 2 / scale;
  730. wallPositionY = wallPositionY + wallHeight2;
  731. }
  732. else if(wallDirection=="S"){
  733. wallPositionY = wallPositionY *-1 + spaceObj.spaceHeight / 2 / scale;
  734. let wallHeight2 = wallHeight / 2 / scale;
  735. wallPositionY = wallPositionY - wallHeight2;
  736. }
  737. if(wallDirection=="E"){
  738. // console.log("模型参数", wallPositionX, spaceObj.spaceWidth)
  739. wallPositionY = wallPositionY * -1;
  740. wallPositionX = wallPositionX + spaceObj.spaceWidth / 2 / scale;
  741. let wallHeight2 = wallHeight / 2 / scale;
  742. wallPositionX = wallPositionX - wallHeight2; // 减去墙体本身的厚度
  743. wallRotateY = Math.PI/2; // 东西墙 模型旋转90度
  744. }else if(wallDirection=="W"){
  745. wallPositionY = wallPositionY *-1;
  746. wallPositionX = wallPositionX - spaceObj.spaceWidth / 2 / scale;
  747. let wallHeight2 = wallHeight / 2 / scale;
  748. wallPositionX = wallPositionX + wallHeight2; // 减去墙体本身的厚度
  749. wallRotateY = Math.PI/2; // 东西墙 模型旋转90度
  750. }
  751. let wallScaleX = modelItem.wallScaleX;
  752. let wallScaleY = 1;
  753. let modelWidth = 10;
  754. if(modelItem.wallType == '7') {
  755. modelWidth = 150
  756. }else if(modelItem.wallType == '21'){
  757. modelWidth = 100
  758. }else if(modelItem.wallType == '22'){
  759. modelWidth = 200
  760. }else if(modelItem.wallType == '23'){
  761. modelWidth = 300
  762. }else if(modelItem.wallType == '24'){
  763. modelWidth = 400
  764. }else if(modelItem.wallType == '25'){
  765. modelWidth = 500
  766. }else if(modelItem.wallType == '26'){
  767. modelWidth = 600
  768. }
  769. let tmdWidth = modelItem.wallWidth;//记录
  770. // console.log("XXXXXXXXXXXXXXXX", modelWidth, spaceObj)
  771. let wallWidth = 0; // 墙体宽度
  772. // 计算墙体的 X Y W H
  773. //说明该面墙壁只使用了一个模型-独占形式
  774. if(modelItem.isStepAsideTopRight == 'true' && modelItem.isStepAsideBottomLeft == 'true'){
  775. if(wallDirection=="S" || wallDirection=="N"){//南北
  776. wallScaleX = spaceObj.spaceWidth / modelWidth;
  777. }else{//东西
  778. wallScaleX = spaceObj.spaceHeight / modelWidth;
  779. }
  780. if((parseInt(modelItem.wallType) >=21 && parseInt(modelItem.wallType) <=26) || parseInt(modelItem.wallType)== 7){
  781. }else{
  782. modelItem.wallWidth = wallScaleX * modelWidth; // 解决模型行拉伸定位问题, 先注释
  783. }
  784. }else{//墙面是多端墙体组合而成的
  785. if(modelItem.isFixedWidth == 'true'){//该墙体锁定宽度-即不可缩放
  786. wallWidth = modelItem.wallWidth; // 墙体宽度
  787. // console.log("模型的尺寸",wallWidth, spaceObj.spaceWidth, spaceObj.centerX)
  788. //起始墙体-南北从左侧算,东西则从上侧计算
  789. if(modelItem.isStepAsideBottomLeft == 'true' || modelItem.isStepAsideTopRight == 'true'){
  790. if(wallDirection=="S" || wallDirection=="N"){//南北
  791. wallPositionX = spaceObj.centerX - (spaceObj.spaceWidth - wallWidth) / 2;
  792. wallPositionX = wallPositionX / scale; // 转换成m
  793. }else{
  794. wallPositionY = -spaceObj.centerY - (spaceObj.spaceHeight - wallWidth) / 2;
  795. wallPositionY = wallPositionY / scale; // 转换成m
  796. }
  797. }else{
  798. if(wallDirection=="S" || wallDirection=="N"){//南北
  799. wallPositionX = lastWallPosition + (wallWidth / 2 / scale);
  800. }else{
  801. wallPositionY = lastWallPosition + (wallWidth / 2 / scale);
  802. }
  803. }
  804. // console.log("模型的尺寸",wallWidth, wallPositionX)
  805. if(modelItem.wallType == 0){
  806. wallScaleX = modelItem.wallWidth / wallHeight;
  807. }else{
  808. console.log("墙体模型的缩放", spaceObj.spaceId,wallDirection, modelItem);
  809. // if(!moveOut){
  810. const curWallType = wallType.find(it=>it.type == modelItem.wallType)
  811. wallScaleX = modelItem.wallWidth / curWallType.width;
  812. console.log("墙体模型的缩小", modelItem,direction,wallDirection);
  813. // }else{
  814. // console.log("墙体模型的放大", wallScaleX);
  815. // }
  816. }
  817. //计算当前墙体占据的整面墙体的大小-方便下一段墙体的计算
  818. if(wallDirection=="S" || wallDirection=="N"){//南北
  819. lastWallPosition = wallPositionX + wallWidth / 2 / scale;
  820. }else{
  821. lastWallPosition = wallPositionY + wallWidth / 2 / scale;
  822. }
  823. // wallPositionY = 1;
  824. }else{//可变墙体-UE编辑器通常把它放到最后一段墙体
  825. wallWidth = 0;
  826. //墙体的宽度是计算得出的
  827. if(wallDirection=="S" || wallDirection=="N"){//南北
  828. wallWidth = (spaceObj.centerX + spaceObj.spaceWidth / 2) - lastWallPosition * scale; // 墙体宽度
  829. // console.log("最后一个模型",spaceObj.centerX, spaceObj.spaceWidth / 2, lastWallPosition)
  830. }else{
  831. wallWidth = (-spaceObj.centerY + spaceObj.spaceHeight / 2) - lastWallPosition * scale; // 墙体宽度
  832. }
  833. wallWidth = wallWidth / scale; // cm转换成m
  834. if(modelItem.wallType == 0){
  835. wallScaleX = wallWidth * wallHeight;
  836. if(wallDirection=="S" || wallDirection=="N"){//南北
  837. wallPositionX = lastWallPosition + wallWidth / 2;
  838. }else{
  839. wallPositionY = lastWallPosition + wallWidth / 2;
  840. }
  841. }
  842. modelItem.wallWidth = wallWidth*scale;//确保单位一致
  843. // wallPositionY = 1;
  844. }
  845. }
  846. console.log("移动墙体模型-空间信息", spaceObj.spaceWidth, spaceObj.centerX, spaceObj.centerY, spaceObj)
  847. console.log("移动墙体模型-墙体信息",spaceObj.spaceId,direction, wallDirection, modelItem.wallType, wallWidth, this.wallList)
  848. //计算得出墙体相应的位置和变形属性
  849. modelItem.wallPositionX = wallPositionX;
  850. modelItem.wallPositionY = wallPositionY;
  851. modelItem.wallScaleX = wallScaleX;
  852. modelItem.wallScaleY = wallScaleY;
  853. modelItem.wallRotateY = wallRotateY;
  854. modelItem.wallWidth = wallWidth;
  855. // 更新数据
  856. if(isComputeWall || direction == wallDirection){
  857. this.gltfWalls.forEach(gltfItem=>{
  858. if(gltfItem.spaceId == spaceObj.spaceId && wallDirection == gltfItem.wallDirection && modelItem.id == gltfItem.wallModelData.id ){
  859. if(direction == wallDirection){ // 墙体移动方向和墙面方向一致则执行位置移动
  860. let tempWallModelData = gltfItem.wallModelData;
  861. tempWallModelData.wallPositionX = wallPositionX
  862. tempWallModelData.wallPositionY = wallPositionY
  863. gltfItem.wallModelData = tempWallModelData;
  864. }else{
  865. gltfItem.wallModelData = JSON.parse(JSON.stringify(modelItem));
  866. gltfItem.willCurWallType = modelItem.willCurWallType
  867. }
  868. if(gltfItem.wallModelData.wallType != 0){
  869. gltfItem.isDidWall = isCreateNewWall;
  870. }
  871. }
  872. })
  873. }
  874. //数据更新到wallList中,确保数据一致性
  875. this.wallList.forEach(wallItem=>{
  876. const walls = JSON.parse(wallItem.wallJson);
  877. // console.log("墙体数据2----------", walls, modelItem);
  878. walls.wallData.forEach(wall=>{
  879. wall.wallModelData.forEach(wallmodel=>{
  880. //从wallList找到这段墙体
  881. if(wall.wallDirection == wallDirection && wallmodel.id == modelItem.id && walls.spaceId == spaceObj.spaceId){
  882. if(wallmodel.wallType == 0 && wallmodel.isFixedWidth == 'true'){
  883. wallmodel.wallWidth = modelItem.wallWidth;
  884. console.log("墙体数据31----实体墙------",spaceObj.spaceId, modelItem.wallWidth, modelItem);
  885. }
  886. if(wallmodel.wallType != 0){
  887. wallmodel.wallWidth = modelItem.wallWidth;
  888. const curWallType = wallType.find(it=>it.type == modelItem.willCurWallType)
  889. if(curWallType){
  890. wallmodel.wallType = curWallType.type;
  891. }
  892. }
  893. }
  894. })
  895. })
  896. wallItem.wallJson = JSON.stringify(walls);
  897. })
  898. })
  899. }
  900. })
  901. // console.log("墙体数据2", this.gltfWalls, this.wallList);
  902. },
  903. //更新墙体模型的位置
  904. updateAllWallHandle(){//spaceList gltfSpaces
  905. console.warn("***updateAllWallHandle***")
  906. this.spaceList.forEach((spaceObj)=>{
  907. // 根据空间,更新前提数据
  908. let wallObj = this.wallList.find((item)=>{
  909. return item.id == spaceObj.wallId;
  910. })
  911. if(wallObj){
  912. let element = JSON.parse(wallObj.wallJson);
  913. // console.warn("****wallObj**",element)
  914. this.computeWallHandleOld(spaceObj, element); // 重新计算-并把空间的计算结果同步到gltfWalls中
  915. }
  916. })
  917. for (let index = 0; index < this.gltfWalls.length; index++) {
  918. const element = this.gltfWalls[index];
  919. this.drawModel(element.wallModelData, null, element, false)
  920. }
  921. },
  922. loadChangeWallModels(item, resolve){
  923. var that = this;
  924. let wallObj = item;
  925. console.log("处理模型替换", item);
  926. if(item.wallModelData.wallWidth == 0){ // 模型隐藏
  927. return resolve();
  928. }
  929. if(item.wallModelData.willCurWallType && item.wallModelData.willCurWallType > 0 ){
  930. const curWallType = wallType.find(it=>it.type == item.wallModelData.willCurWallType)
  931. console.log("加载的模型", item, item.wallModelData.willCurWallType, curWallType);
  932. if(!curWallType){
  933. return resolve();
  934. }
  935. that.loader.load(curWallType.url, ( gltf ) => {
  936. // 旧的模型
  937. let spaceInitMatrix = [];//记录下动画创建时的初始变换矩阵
  938. wallObj.instancedMeshIndexList.forEach(it=>{
  939. let _index = it.instancedMeshIndex;
  940. let instancedMesh = this.instancedMeshList[_index];//获取网格实例
  941. let startMatrix = new THREE.Matrix4();//定义一个四维矩阵
  942. instancedMesh.getMatrixAt(it.instancedAtIndex,startMatrix);//获取当前几何体的四维矩阵到stratMatrix里面
  943. spaceInitMatrix.push({
  944. index:_index,
  945. matrix:startMatrix.clone(),
  946. })
  947. });
  948. wallObj.instancedMeshIndexList.forEach(it=>{
  949. let _index = it.instancedMeshIndex;
  950. let instancedMesh = this.instancedMeshList[_index];//获取网格实例
  951. let tmp = spaceInitMatrix.find(it=>it.index==_index);
  952. let stratMatrix = tmp.matrix.clone(); //获取初始变换矩阵
  953. // // 计算变化后的位置:位移后的位置 是 当前几何体的位置参数 加上 模型移动后的位置偏移量
  954. let scaleMatrix = new THREE.Matrix4(); //定义一个缩放变化矩阵
  955. let panMatrix = new THREE.Matrix4(); //定义一个平移变化矩阵
  956. scaleMatrix.makeScale(0,0,0); //获得缩放变化矩阵
  957. panMatrix.makeTranslation(0,0,0); //获得平移变化矩阵
  958. stratMatrix.multiply(scaleMatrix).premultiply(panMatrix);//通过矩阵计算获得最终的形变矩阵
  959. instancedMesh.instanceMatrix.needsUpdate = true;//更新之前,必须开启开关
  960. instancedMesh.setMatrixAt(it.instancedAtIndex,stratMatrix);//更新几何体的世界矩阵
  961. })
  962. let newWallObj = JSON.parse(JSON.stringify(item))
  963. const wallType = item.wallModelData.willCurWallType;
  964. console.log("重新组合新模型数据", newWallObj, item.wallModelData, wallType);
  965. newWallObj.willCurWallType = -1;
  966. let wallModelData = newWallObj.wallModelData;
  967. wallModelData.wallScaleX = 1;
  968. wallModelData.wallScaleY = 1;
  969. wallModelData.lastWallType = item.wallModelData.wallType;
  970. wallModelData.wallType = wallType;
  971. wallModelData.willCurWallType = -1;
  972. newWallObj.wallModelData = wallModelData;
  973. newWallObj.wallScaleX = 1;
  974. newWallObj.wallScaleY = 1;
  975. let realWallArr = this.preWallData([newWallObj]);
  976. const realData = realWallArr[0];
  977. // 新的模型
  978. gltf.scene.traverse((child)=> {
  979. if (child.isMesh && child.visible) {
  980. let instancedMesh = new THREE.InstancedMesh(child.geometry.clone(), child.material.clone(), realData.list.length);
  981. this.instancedMeshList.push(instancedMesh);
  982. //realData 该模型被重复使用时的每一次的形变参数等
  983. realData.list && realData.list.forEach((it,i)=>{
  984. gltf.scene.position.set(item.wallPositionX, 0, item.wallPositionY);
  985. gltf.scene.scale.set(1, 1, 1);
  986. gltf.scene.rotation.y = item.wallRotateY;
  987. gltf.scene.updateMatrixWorld();//更新世界坐标-这样,子模型也同步更新了
  988. instancedMesh.setMatrixAt(i, child.matrixWorld);
  989. instancedMesh.instanceMatrix.needsUpdate = true;
  990. // instancedMesh.setColorAt(i, child.material.color);
  991. // instancedMesh.instanceColor.needsUpdate = true;
  992. // console.log("***matrixWorld***",child.matrixWorld);
  993. let gltfWall = that.gltfWalls.find(gltfWall=>gltfWall.uniId==it.uniId);//判断是否已经添加过
  994. if(!gltfWall){
  995. let md = {
  996. uniId:it.uniId,//模型实例的唯一标识
  997. spaceId:it.spaceId,
  998. instancedMeshIndexList:[//标识网格实例数组的序号 以及 当前几何体 在网格实例的序号
  999. {instancedMeshIndex:this.instancedMeshList.length-1,instancedAtIndex:i},
  1000. ],
  1001. // id:child.id,//几何体的id
  1002. // name:child.name,//几何体的id
  1003. wallPositionX:item.wallPositionX,
  1004. wallPositionY:item.wallPositionY,
  1005. wallScaleX:1,
  1006. wallScaleY:1,
  1007. wallRotateY:item.wallRotateY,
  1008. wallWidth:item.wallWidth,
  1009. wallModelData:wallModelData,
  1010. wallModelInitData:item, // 保留初始化墙体数据,方便空间变形计算缩放比例
  1011. wallDirection:it.wallDirection,
  1012. willCurWallType: -1, // 即将成为当前模型,作用于动画加载完替换
  1013. lastWallType:wallModelData.lastWallType // 上一次墙体模型
  1014. };
  1015. that.gltfWalls.push(md);
  1016. }else{
  1017. gltfWall.instancedMeshIndexList.push({
  1018. instancedMeshIndex:this.instancedMeshList.length-1,instancedAtIndex:i
  1019. })
  1020. }
  1021. })
  1022. instancedMesh.userType = "mesh";
  1023. that.scene.add(instancedMesh);
  1024. }
  1025. });
  1026. resolve();
  1027. })
  1028. }
  1029. resolve();
  1030. }
  1031. }
  1032. }