ClipPlaneRotator.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. var rotateAngleParameter, rotateSpeed, rotateState, isMouseUp;
  2. var rotateLine, rotateLineVector, nearClipNormal, rotateTask, rotatePlane;
  3. //初始化旋转参数
  4. function initRotateClipPlaneArgs() {
  5. rotateState = RotateState.None;
  6. isMouseUp = false;
  7. rotatePlane = new THREE.Plane();
  8. rotateAngleParameter = 0;
  9. rotateSpeed = 0.002;
  10. }
  11. //设置旋转相关信息
  12. function addRotateInfo() {
  13. if (ClipPlaneManager.activeMeshInfo == undefined) return;
  14. if (ClipPlaneManager.isActivePlaneCompleteClipped()) {
  15. LinesDrawingManager.hideRotateLine();
  16. return;
  17. }
  18. let meshBorders = ClipPlaneManager.getActiveMeshBorders();
  19. if (meshBorders.length < 1) return;
  20. setRotateLine();
  21. LinesDrawingManager.showRotateLine(rotateLine);
  22. SpriteManager.showRotateSprite();
  23. nearClipNormal = ClipPlaneManager.getNeighbourPlaneNormal(
  24. rotateLine,
  25. ClipPlaneManager.activeMeshInfo.Mesh
  26. );
  27. //设置旋转轴
  28. function setRotateLine() {
  29. if (ClipPlaneManager.activeMeshInfo.Point == undefined) {
  30. rotateLine = meshBorders[0];
  31. } else {
  32. let pointDistance = -1;
  33. let projectivePoint = new THREE.Vector3();
  34. let mouseDownPoint = ClipPlaneManager.activeMeshInfo.Point;
  35. //取离鼠标按下点最近的边作为rotateLine
  36. meshBorders.forEach((meshBorder) => {
  37. meshBorder.closestPointToPoint(mouseDownPoint, false, projectivePoint);
  38. let distance = mouseDownPoint.distanceTo(projectivePoint);
  39. if (pointDistance > distance || pointDistance < 0) {
  40. pointDistance = distance;
  41. rotateLine = meshBorder;
  42. }
  43. });
  44. }
  45. rotateAngleParameter = 0;
  46. }
  47. }
  48. //移除旋转信息
  49. function removeRotateInfo() {
  50. LinesDrawingManager.hideRotateLine();
  51. SpriteManager.hideRotateSprite();
  52. rotateLine = undefined;
  53. rotateStateReset();
  54. }
  55. //添加旋转线程开始旋转
  56. function addRotateTask(direction) {
  57. rotateAngleParameter = 0;
  58. if (rotateState == RotateState.MaximumAngle) {
  59. rotateState = RotateState.None;
  60. }
  61. rotateLineVector = rotateLine.start.clone().sub(rotateLine.end).normalize();
  62. rotateClipPlane(direction);
  63. document.addEventListener(OSHelper.touchEnd, OnRotateMouseUp, false);
  64. rotateTask = setInterval(function () {
  65. rotateClipPlane(direction);
  66. }, 30);
  67. }
  68. //旋转切面
  69. async function rotateClipPlane(direction) {
  70. resetMouseUpState();
  71. if (!canRotate()) return;
  72. let rotateAngle =
  73. direction > 0
  74. ? rotateAngleParameter + rotateSpeed
  75. : rotateAngleParameter - rotateSpeed;
  76. if (!isInRotateAngleRanges(rotateAngle)) return;
  77. //开始旋转
  78. rotateState = RotateState.Rotating;
  79. //获取旋转后平面的法向量
  80. let vector = getRotatedNormal();
  81. if (isRotateToMaximumAngle(vector)) {
  82. return;
  83. }
  84. //设置新切面
  85. rotatePlane.setFromNormalAndCoplanarPoint(vector, rotateLine.end);
  86. let success = await refreshClipMesh(
  87. rotatePlane,
  88. ClipPlaneManager.activeMeshInfo.Mesh.Object,
  89. ClipPlaneManager.activeMeshInfo.Mesh.ImageName,
  90. refreshClipMeshCallback
  91. );
  92. if (!success) {
  93. rotateState = RotateState.RotateEnd;
  94. }
  95. function canRotate() {
  96. if (
  97. rotateState === RotateState.Rotating ||
  98. rotateState === RotateState.MaximumAngle ||
  99. ClipPlaneManager.activeMeshInfo === undefined ||
  100. rotateLine === undefined
  101. ) {
  102. return false;
  103. }
  104. return true;
  105. }
  106. function resetMouseUpState() {
  107. if (rotateAngleParameter == 0) {
  108. isMouseUp = false;
  109. }
  110. }
  111. //旋转角参数是否在-1到1范围内
  112. function isInRotateAngleRanges(rotateAngle) {
  113. if (rotateAngle > 1 || rotateAngle < -1) {
  114. return false;
  115. }
  116. return true;
  117. }
  118. //获取旋转后平面的法向量
  119. function getRotatedNormal() {
  120. let vector = ClipPlaneManager.activeMeshInfo.Mesh.Normal.clone();
  121. let normalVector = new THREE.Vector3();
  122. //切面法向量与旋转轴叉乘得到旋转方向向量
  123. normalVector.crossVectors(rotateLineVector, vector);
  124. if (rotateAngle < 0) {
  125. normalVector.negate();
  126. }
  127. //设置旋转后的法向量(平面法向量沿叉乘方向旋转)
  128. vector.lerp(normalVector, Math.abs(rotateAngle)).normalize();
  129. return vector;
  130. }
  131. //判断是否旋转到了极限位置 (旋转后与相邻面的夹角是否超过了限定值)
  132. function isRotateToMaximumAngle(vector) {
  133. if (nearClipNormal == undefined) return false;
  134. if (!ClipPlaneManager.isWithinRotateRange(vector, nearClipNormal)) {
  135. rotateState = RotateState.MaximumAngle;
  136. return true;
  137. }
  138. return false;
  139. }
  140. function refreshClipMeshCallback() {
  141. if (rotateState == RotateState.Rotating) {
  142. ClipPlaneManager.activeMeshInfo.Mesh.Plane.set(
  143. rotatePlane.normal.clone(),
  144. rotatePlane.constant
  145. );
  146. if (isMouseUp) {
  147. ClipPlaneManager.activeMeshInfo.Mesh.Normal =
  148. ClipPlaneManager.activeMeshInfo.Mesh.Plane.normal.clone();
  149. rotateAngleParameter = 0;
  150. isMouseUp = false;
  151. } else {
  152. rotateAngleParameter = rotateAngle;
  153. }
  154. rotateState = RotateState.RotateEnd;
  155. }
  156. }
  157. }
  158. //旋转时鼠标抬起事件
  159. function OnRotateMouseUp() {
  160. clearInterval(rotateTask);
  161. if (ClipPlaneManager.activeMeshInfo != undefined) {
  162. isMouseUp = true;
  163. ClipPlaneManager.activeMeshInfo.Mesh.Normal =
  164. ClipPlaneManager.activeMeshInfo.Mesh.Plane.normal.clone();
  165. ClipPlaneManager.activeMeshInfo.Mesh.Index = undefined;
  166. }
  167. rotateAngleParameter = 0;
  168. document.body.style.cursor = "default";
  169. document.removeEventListener(OSHelper.touchEnd, OnRotateMouseUp, false);
  170. }
  171. //重置旋转状态
  172. function rotateStateReset() {
  173. clearInterval(rotateTask);
  174. rotateAngleParameter = 0;
  175. if (rotateState == RotateState.MaximumAngle) {
  176. rotateState = RotateState.None;
  177. }
  178. }