var rotateAngleParameter, rotateSpeed, rotateState, isMouseUp; var rotateLine, rotateLineVector, nearClipNormal, rotateTask, rotatePlane; //初始化旋转参数 function initRotateClipPlaneArgs() { rotateState = RotateState.None; isMouseUp = false; rotatePlane = new THREE.Plane(); rotateAngleParameter = 0; rotateSpeed = 0.002; } //设置旋转相关信息 function addRotateInfo() { if (ClipPlaneManager.activeMeshInfo == undefined) return; if (ClipPlaneManager.isActivePlaneCompleteClipped()) { LinesDrawingManager.hideRotateLine(); return; } let meshBorders = ClipPlaneManager.getActiveMeshBorders(); if (meshBorders.length < 1) return; setRotateLine(); LinesDrawingManager.showRotateLine(rotateLine); SpriteManager.showRotateSprite(); nearClipNormal = ClipPlaneManager.getNeighbourPlaneNormal( rotateLine, ClipPlaneManager.activeMeshInfo.Mesh ); //设置旋转轴 function setRotateLine() { if (ClipPlaneManager.activeMeshInfo.Point == undefined) { rotateLine = meshBorders[0]; } else { let pointDistance = -1; let projectivePoint = new THREE.Vector3(); let mouseDownPoint = ClipPlaneManager.activeMeshInfo.Point; //取离鼠标按下点最近的边作为rotateLine meshBorders.forEach((meshBorder) => { meshBorder.closestPointToPoint(mouseDownPoint, false, projectivePoint); let distance = mouseDownPoint.distanceTo(projectivePoint); if (pointDistance > distance || pointDistance < 0) { pointDistance = distance; rotateLine = meshBorder; } }); } rotateAngleParameter = 0; } } //移除旋转信息 function removeRotateInfo() { LinesDrawingManager.hideRotateLine(); SpriteManager.hideRotateSprite(); rotateLine = undefined; rotateStateReset(); } //添加旋转线程开始旋转 function addRotateTask(direction) { rotateAngleParameter = 0; if (rotateState == RotateState.MaximumAngle) { rotateState = RotateState.None; } rotateLineVector = rotateLine.start.clone().sub(rotateLine.end).normalize(); rotateClipPlane(direction); document.addEventListener(OSHelper.touchEnd, OnRotateMouseUp, false); rotateTask = setInterval(function () { rotateClipPlane(direction); }, 30); } //旋转切面 async function rotateClipPlane(direction) { resetMouseUpState(); if (!canRotate()) return; let rotateAngle = direction > 0 ? rotateAngleParameter + rotateSpeed : rotateAngleParameter - rotateSpeed; if (!isInRotateAngleRanges(rotateAngle)) return; //开始旋转 rotateState = RotateState.Rotating; //获取旋转后平面的法向量 let vector = getRotatedNormal(); if (isRotateToMaximumAngle(vector)) { return; } //设置新切面 rotatePlane.setFromNormalAndCoplanarPoint(vector, rotateLine.end); let success = await refreshClipMesh( rotatePlane, ClipPlaneManager.activeMeshInfo.Mesh.Object, ClipPlaneManager.activeMeshInfo.Mesh.ImageName, refreshClipMeshCallback ); if (!success) { rotateState = RotateState.RotateEnd; } function canRotate() { if ( rotateState === RotateState.Rotating || rotateState === RotateState.MaximumAngle || ClipPlaneManager.activeMeshInfo === undefined || rotateLine === undefined ) { return false; } return true; } function resetMouseUpState() { if (rotateAngleParameter == 0) { isMouseUp = false; } } //旋转角参数是否在-1到1范围内 function isInRotateAngleRanges(rotateAngle) { if (rotateAngle > 1 || rotateAngle < -1) { return false; } return true; } //获取旋转后平面的法向量 function getRotatedNormal() { let vector = ClipPlaneManager.activeMeshInfo.Mesh.Normal.clone(); let normalVector = new THREE.Vector3(); //切面法向量与旋转轴叉乘得到旋转方向向量 normalVector.crossVectors(rotateLineVector, vector); if (rotateAngle < 0) { normalVector.negate(); } //设置旋转后的法向量(平面法向量沿叉乘方向旋转) vector.lerp(normalVector, Math.abs(rotateAngle)).normalize(); return vector; } //判断是否旋转到了极限位置 (旋转后与相邻面的夹角是否超过了限定值) function isRotateToMaximumAngle(vector) { if (nearClipNormal == undefined) return false; if (!ClipPlaneManager.isWithinRotateRange(vector, nearClipNormal)) { rotateState = RotateState.MaximumAngle; return true; } return false; } function refreshClipMeshCallback() { if (rotateState == RotateState.Rotating) { ClipPlaneManager.activeMeshInfo.Mesh.Plane.set( rotatePlane.normal.clone(), rotatePlane.constant ); if (isMouseUp) { ClipPlaneManager.activeMeshInfo.Mesh.Normal = ClipPlaneManager.activeMeshInfo.Mesh.Plane.normal.clone(); rotateAngleParameter = 0; isMouseUp = false; } else { rotateAngleParameter = rotateAngle; } rotateState = RotateState.RotateEnd; } } } //旋转时鼠标抬起事件 function OnRotateMouseUp() { clearInterval(rotateTask); if (ClipPlaneManager.activeMeshInfo != undefined) { isMouseUp = true; ClipPlaneManager.activeMeshInfo.Mesh.Normal = ClipPlaneManager.activeMeshInfo.Mesh.Plane.normal.clone(); ClipPlaneManager.activeMeshInfo.Mesh.Index = undefined; } rotateAngleParameter = 0; document.body.style.cursor = "default"; document.removeEventListener(OSHelper.touchEnd, OnRotateMouseUp, false); } //重置旋转状态 function rotateStateReset() { clearInterval(rotateTask); rotateAngleParameter = 0; if (rotateState == RotateState.MaximumAngle) { rotateState = RotateState.None; } }