|
|
@@ -54,7 +54,7 @@
|
|
|
import {Cube} from '@/utils/cube'
|
|
|
import {Wall} from '@/utils/wall'
|
|
|
import { initAxesHelper } from '@/utils/initScene'
|
|
|
- import { ObjectSelect } from '@/utils/objectSelect'
|
|
|
+ import { ObjectSelect , clearSelect} from '@/utils/objectSelect'
|
|
|
import { fullscreenToggel } from '@/utils/screen'
|
|
|
import { getWallData } from '@/stores/data'
|
|
|
import gltfJson from '../../gltf/gltf.json'
|
|
|
@@ -63,6 +63,7 @@
|
|
|
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
|
|
|
import { DragControls } from 'three/examples/jsm/controls/DragControls.js';
|
|
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
|
+ import Stats from 'three/examples/jsm/libs/stats.module.js'
|
|
|
import { ElLoading } from 'element-plus'
|
|
|
|
|
|
const dom = ref<HTMLDivElement>()
|
|
|
@@ -70,6 +71,7 @@
|
|
|
var cameraPos = {"y":200, "z":600};
|
|
|
let selMesh:any
|
|
|
let outlinePass: any;
|
|
|
+ let sellinePass: any;
|
|
|
var scene:any;
|
|
|
var settings = {selMesh: selMesh, color: '#ff0000' , x: 0, y: 0, z:0, rx:0, ry:0, rz:0, sx:1, sy:1, sz:1}
|
|
|
let pathname:any;
|
|
|
@@ -96,6 +98,14 @@
|
|
|
}
|
|
|
showView();
|
|
|
|
|
|
+ // const showStats =() =>{
|
|
|
+ // var stats = new Stats();
|
|
|
+ // stats.dom.style.position = 'absolute';
|
|
|
+ // stats.dom.style.top = '45px';
|
|
|
+ // document.body.appendChild(stats.dom);
|
|
|
+ // }
|
|
|
+ // showStats();
|
|
|
+
|
|
|
const isFullScreen=()=>{
|
|
|
isShowView(false);
|
|
|
fullscreenToggel();
|
|
|
@@ -163,7 +173,7 @@
|
|
|
|
|
|
function addGeometry(val:string){
|
|
|
var cube = initGeometry(val);
|
|
|
- var minY = calculateModelBottomY(cube);
|
|
|
+ var minY = calculateModelBottomY(cube) * cube.scale.y;
|
|
|
minY = -minY + 5
|
|
|
cube.position.set(0, minY, 0);
|
|
|
dragModel(cube);
|
|
|
@@ -188,13 +198,19 @@
|
|
|
if(!scaleX)scaleX = 1;
|
|
|
if(!scaleY)scaleY = 1;
|
|
|
if(!scaleZ)scaleZ = 1;
|
|
|
+ baseScaleX = scaleX;
|
|
|
+ baseScaleY = scaleY;
|
|
|
+ baseScaleZ = scaleZ;
|
|
|
originaMesh.scale.set(scaleX, scaleY, scaleZ)
|
|
|
- var box = new THREE.Box3().setFromObject(originaMesh);
|
|
|
var minY = calculateModelBottomY(originaMesh);
|
|
|
if(posY){
|
|
|
originaMesh.position.set(0,posY,0);
|
|
|
}else{
|
|
|
- minY = (-minY/100) + 5
|
|
|
+ if(originaMesh.scale.y<1){
|
|
|
+ minY = (-minY * originaMesh.scale.y) + 5
|
|
|
+ }else{
|
|
|
+ minY = 5
|
|
|
+ }
|
|
|
originaMesh.position.set(0,minY,0);
|
|
|
}
|
|
|
originaMesh.name = "file_"+modelName+"_"+new Date().getTime();
|
|
|
@@ -219,7 +235,7 @@
|
|
|
let originaMesh = mod.scene.children[0]
|
|
|
originaMesh.scale.set(params.sx, params.sy, params.sz)
|
|
|
originaMesh.position.set(params.x,params.y,params.z);
|
|
|
- originaMesh.rotation.set(params.rx, params.ry, params.rz)
|
|
|
+ originaMesh.rotation.set(degreesArc(params.rx), degreesArc(params.ry), degreesArc(params.rz))
|
|
|
originaMesh.name = params.name;
|
|
|
dragModel(originaMesh);
|
|
|
scene.add(originaMesh)
|
|
|
@@ -240,10 +256,11 @@
|
|
|
dragControls.addEventListener("dragend", ()=>{
|
|
|
control.enabled = true;
|
|
|
if(settings.selMesh && model.name == settings.selMesh.name){
|
|
|
- settings.x = model.position.x;
|
|
|
settings.y = model.position.y;
|
|
|
+ settings.x = model.position.x;
|
|
|
settings.z = model.position.z;
|
|
|
}
|
|
|
+ checkY(model);
|
|
|
})
|
|
|
// 监听mouseDown事件
|
|
|
renderer.domElement.addEventListener('mousedown', (event) => {
|
|
|
@@ -296,9 +313,9 @@
|
|
|
const baseX = getDecimalDigits(baseScaleX);
|
|
|
const baseY = getDecimalDigits(baseScaleY);
|
|
|
const baseZ = getDecimalDigits(baseScaleZ);
|
|
|
- gui.add(settings, 'sx', -baseScaleX*1000, baseScaleX*1000).name('缩放X').step(0.001);
|
|
|
- gui.add(settings, 'sy', -baseScaleY*1000, baseScaleY*1000).name('缩放Y').step(0.001);
|
|
|
- gui.add(settings, 'sz', -baseScaleZ*1000, baseScaleZ*1000).name('缩放Z').step(0.001);
|
|
|
+ gui.add(settings, 'sx', -baseScaleX*1000, baseScaleX*1000).name('缩放X').step(baseScaleX/10);
|
|
|
+ gui.add(settings, 'sy', -baseScaleY*1000, baseScaleY*1000).name('缩放Y').step(baseScaleY/10);
|
|
|
+ gui.add(settings, 'sz', -baseScaleZ*1000, baseScaleZ*1000).name('缩放Z').step(baseScaleY/10);
|
|
|
}
|
|
|
|
|
|
const initLight = () => {
|
|
|
@@ -337,12 +354,16 @@
|
|
|
prevHeight = currentHeight;
|
|
|
})
|
|
|
|
|
|
- window.addEventListener('contextmenu', ()=>{
|
|
|
+ window.addEventListener('contextmenu', (e)=>{
|
|
|
settings.selMesh = null;
|
|
|
outlinePass.selectedObjects = [];
|
|
|
+ sellinePass.selectedObjects = [];
|
|
|
+ clearSelect();
|
|
|
+ drawer.value = false;
|
|
|
if(gui){
|
|
|
gui.destroy();
|
|
|
}
|
|
|
+ e.stopPropagation()
|
|
|
})
|
|
|
|
|
|
function updateFloor(){
|
|
|
@@ -450,14 +471,28 @@
|
|
|
outlinePass.visibleEdgeColor.set('#B31985');//包围线颜色
|
|
|
outlinePass.hiddenEdgeColor.set('#190a05');//被遮挡的边界线颜色
|
|
|
}
|
|
|
+
|
|
|
+ const initSelLine= () =>{
|
|
|
+ let vector = new THREE.Vector2(window.innerWidth, window.innerWidth);
|
|
|
+ sellinePass = new OutlinePass(vector, scene, camera);
|
|
|
+ sellinePass.edgeStrength = 10;//包围线浓度
|
|
|
+ sellinePass.edgeGlow = 0.1;//边缘线范围
|
|
|
+ sellinePass.edgeThickness = 1;//边缘线浓度
|
|
|
+ sellinePass.pulsePeriod = 2;//包围线闪烁评率
|
|
|
+ sellinePass.visibleEdgeColor.set('#1E90FF');//包围线颜色
|
|
|
+ sellinePass.hiddenEdgeColor.set('#B0E0E6');//被遮挡的边界线颜色
|
|
|
+ }
|
|
|
+
|
|
|
const initComposer =() =>{
|
|
|
let renderPass = new RenderPass(scene, camera);
|
|
|
let composer = new EffectComposer(renderer);
|
|
|
composer.addPass(renderPass);
|
|
|
composer.addPass(outlinePass);
|
|
|
+ composer.addPass(sellinePass)
|
|
|
return composer;
|
|
|
}
|
|
|
initoutLine();
|
|
|
+ initSelLine();
|
|
|
let composer = initComposer();
|
|
|
|
|
|
// 计算模型底部Y坐标的函数
|
|
|
@@ -475,6 +510,25 @@
|
|
|
return minY;
|
|
|
}
|
|
|
|
|
|
+ // 计算模型底部Y坐标的函数
|
|
|
+ function calculateModelTopY(object3D:any) {
|
|
|
+ let maxY = Infinity;
|
|
|
+ object3D.traverse(function (child:any) {
|
|
|
+ if (child.isMesh) {
|
|
|
+ const geometry = child.geometry;
|
|
|
+ if (geometry.boundingBox === null) {
|
|
|
+ geometry.computeBoundingBox();
|
|
|
+ }
|
|
|
+ if(maxY == Infinity){
|
|
|
+ maxY = geometry.boundingBox.max.y;
|
|
|
+ }else{
|
|
|
+ maxY = Math.max(maxY, geometry.boundingBox.max.y);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return maxY;
|
|
|
+ }
|
|
|
+
|
|
|
const clickHandle = (selectObject:any, frm:number) =>{
|
|
|
drawer.value = false;
|
|
|
if(!isOperater.value){
|
|
|
@@ -534,7 +588,11 @@
|
|
|
var box = new THREE.Box3().setFromObject(settings.selMesh);
|
|
|
var minY = calculateModelBottomY(settings.selMesh);
|
|
|
if(settings.selMesh.name.startsWith("file_")){
|
|
|
- minY = (-minY/100) + 5
|
|
|
+ if(settings.selMesh.scale.y > 1){
|
|
|
+ minY = 5
|
|
|
+ }else{
|
|
|
+ minY = (-minY*settings.selMesh.scale.y) + 5
|
|
|
+ }
|
|
|
}else{
|
|
|
minY = -minY + 5
|
|
|
}
|
|
|
@@ -547,7 +605,7 @@
|
|
|
initGUI(-x, x, minY, y_top, -z, z);
|
|
|
}
|
|
|
|
|
|
- ObjectSelect(scene, camera, outlinePass, clickHandle)
|
|
|
+ ObjectSelect(scene, camera, outlinePass, sellinePass, clickHandle)
|
|
|
|
|
|
const updateModel =() =>{
|
|
|
if(settings.selMesh
|
|
|
@@ -580,9 +638,7 @@
|
|
|
}
|
|
|
|
|
|
// 渲染函数
|
|
|
- const clock = new THREE.Clock()
|
|
|
const render = () => {
|
|
|
- const delta = clock.getDelta()
|
|
|
requestAnimationFrame(render)
|
|
|
renderer.render(scene, camera)
|
|
|
composer.render();
|
|
|
@@ -700,6 +756,7 @@
|
|
|
gui.destroy()
|
|
|
gui = null;
|
|
|
}
|
|
|
+
|
|
|
// var modelName = settings.selMesh;
|
|
|
// if (scene.getObjectByName(modelName)) {
|
|
|
// var model = scene.getObjectByName(modelName);
|
|
|
@@ -727,27 +784,108 @@
|
|
|
if (event.key === 'Escape'|| event.keyCode === 27) {
|
|
|
isShowView(true);
|
|
|
}
|
|
|
+ if((event.ctrlKey || event.key.indexOf('Control') > -1) && (event.key.indexOf("Up") > -1|| event.keyCode === 38)){
|
|
|
+ moveObject('Y+');
|
|
|
+ }else
|
|
|
+ if((event.ctrlKey || event.key.indexOf('Control') > -1) && (event.key.indexOf("Down") > -1 || event.keyCode === 40)){
|
|
|
+ moveObject('Y-');
|
|
|
+ }else
|
|
|
if(event.key.indexOf("Up") > -1|| event.keyCode === 38){
|
|
|
+ moveObject('Z-');
|
|
|
+ }else
|
|
|
+ if(event.key.indexOf("Down") > -1 || event.keyCode === 40){
|
|
|
+ moveObject('Z+');
|
|
|
+ }else
|
|
|
+ if(event.key.indexOf("Left") > -1|| event.keyCode === 37){
|
|
|
+ moveObject('X-');
|
|
|
+ }else
|
|
|
+ if(event.key.indexOf("Right") > -1 || event.keyCode === 39){
|
|
|
+ moveObject('X+');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ function moveObject(axes:any){
|
|
|
+ if(axes == 'Y+'){
|
|
|
if(settings.selMesh){
|
|
|
- settings.z = settings.z - 1
|
|
|
+ settings.y = settings.y + 1
|
|
|
+ }
|
|
|
+ var objects = sellinePass.selectedObjects;
|
|
|
+ for(var ix in objects){
|
|
|
+ var obj = objects[ix]
|
|
|
+ obj.position.y = obj.position.y + 1
|
|
|
}
|
|
|
}
|
|
|
- if(event.key.indexOf("Down") > -1 || event.keyCode === 40){
|
|
|
+ if(axes == 'Y-'){
|
|
|
if(settings.selMesh){
|
|
|
- settings.z = settings.z + 1
|
|
|
+ settings.y = settings.y - 1
|
|
|
+ checkY(settings.selMesh)
|
|
|
+ }
|
|
|
+ var objects = sellinePass.selectedObjects;
|
|
|
+ for(var ix in objects){
|
|
|
+ var obj = objects[ix]
|
|
|
+ obj.position.y = obj.position.y - 1
|
|
|
+ checkY(settings.selMesh)
|
|
|
}
|
|
|
}
|
|
|
- if(event.key.indexOf("Left") > -1|| event.keyCode === 37){
|
|
|
+
|
|
|
+ if(axes == 'X+'){
|
|
|
+ if(settings.selMesh){
|
|
|
+ settings.x = settings.x + 1
|
|
|
+ }
|
|
|
+ var objects = sellinePass.selectedObjects;
|
|
|
+ for(var ix in objects){
|
|
|
+ var obj = objects[ix]
|
|
|
+ obj.position.x = obj.position.x + 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(axes == 'X-'){
|
|
|
if(settings.selMesh){
|
|
|
settings.x = settings.x - 1
|
|
|
}
|
|
|
+ var objects = sellinePass.selectedObjects;
|
|
|
+ for(var ix in objects){
|
|
|
+ var obj = objects[ix]
|
|
|
+ obj.position.x = obj.position.x - 1
|
|
|
+ }
|
|
|
}
|
|
|
- if(event.key.indexOf("Right") > -1 || event.keyCode === 39){
|
|
|
+
|
|
|
+ if(axes == 'Z+'){
|
|
|
if(settings.selMesh){
|
|
|
- settings.x = settings.x + 1
|
|
|
+ settings.z = settings.z + 1
|
|
|
+ }
|
|
|
+ var objects = sellinePass.selectedObjects;
|
|
|
+ for(var ix in objects){
|
|
|
+ var obj = objects[ix]
|
|
|
+ obj.position.z = obj.position.z + 1
|
|
|
}
|
|
|
}
|
|
|
- });
|
|
|
+ if(axes == 'Z-'){
|
|
|
+ if(settings.selMesh){
|
|
|
+ settings.z = settings.z - 1
|
|
|
+ }
|
|
|
+ var objects = sellinePass.selectedObjects;
|
|
|
+ for(var ix in objects){
|
|
|
+ var obj = objects[ix]
|
|
|
+ obj.position.z = obj.position.z - 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function checkY(model:any){
|
|
|
+ var minY = 5;
|
|
|
+ var boundY = calculateModelBottomY(model);
|
|
|
+ if(model.name.startsWith("file_")){
|
|
|
+ if(model.scale.y < 1){
|
|
|
+ minY = Math.abs(boundY * model.scale.y) + 5;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ minY = -boundY + 5;
|
|
|
+ }
|
|
|
+ if(model.position.y < minY){
|
|
|
+ model.position.y = minY;
|
|
|
+ settings.y = minY;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
function handleFileUpload(event:any){
|
|
|
const file = event.raw;
|