Profile.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. import * as THREE from "../../libs/three.js/build/three.module.js";
  2. import {Utils} from "../utils.js";
  3. export class Profile extends THREE.Object3D{
  4. constructor () {
  5. super();
  6. this.constructor.counter = (this.constructor.counter === undefined) ? 0 : this.constructor.counter + 1;
  7. this.name = 'Profile_' + this.constructor.counter;
  8. this.points = [];
  9. this.spheres = [];
  10. this.edges = [];
  11. this.boxes = [];
  12. this.width = 1;
  13. this.height = 20;
  14. this._modifiable = true;
  15. this.sphereGeometry = new THREE.SphereGeometry(0.4, 10, 10);
  16. this.color = new THREE.Color(0xff0000);
  17. this.lineColor = new THREE.Color(0xff0000);
  18. }
  19. createSphereMaterial () {
  20. let sphereMaterial = new THREE.MeshLambertMaterial({
  21. //shading: THREE.SmoothShading,
  22. color: 0xff0000,
  23. depthTest: false,
  24. depthWrite: false}
  25. );
  26. return sphereMaterial;
  27. };
  28. getSegments () {
  29. let segments = [];
  30. for (let i = 0; i < this.points.length - 1; i++) {
  31. let start = this.points[i].clone();
  32. let end = this.points[i + 1].clone();
  33. segments.push({start: start, end: end});
  34. }
  35. return segments;
  36. }
  37. getSegmentMatrices () {
  38. let segments = this.getSegments();
  39. let matrices = [];
  40. for (let segment of segments) {
  41. let {start, end} = segment;
  42. let box = new THREE.Object3D();
  43. let length
  44. if(window.axisYup){
  45. length = start.clone().setY(0).distanceTo(end.clone().setY(0));
  46. box.scale.set(length, 10000, this.width); //???
  47. }else{
  48. length = start.clone().setZ(0).distanceTo(end.clone().setZ(0));
  49. box.scale.set(length, 10000, this.width);
  50. box.up.set(0, 0, 1);
  51. }
  52. let center = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);
  53. let diff = new THREE.Vector3().subVectors(end, start);
  54. let target = new THREE.Vector3(diff.y, -diff.x, 0);
  55. box.position.set(0, 0, 0);
  56. box.lookAt(target);
  57. box.position.copy(center);
  58. box.updateMatrixWorld();
  59. matrices.push(box.matrixWorld);
  60. }
  61. return matrices;
  62. }
  63. addMarker (point) {
  64. this.points.push(point);
  65. let sphere = new THREE.Mesh(this.sphereGeometry, this.createSphereMaterial());
  66. this.add(sphere);
  67. this.spheres.push(sphere);
  68. // edges & boxes
  69. if (this.points.length > 1) {
  70. let lineGeometry = new THREE.Geometry();
  71. lineGeometry.vertices.push(new THREE.Vector3(), new THREE.Vector3());
  72. lineGeometry.colors.push(this.lineColor, this.lineColor, this.lineColor);
  73. let lineMaterial = new THREE.LineBasicMaterial({
  74. vertexColors: THREE.VertexColors,
  75. lineWidth: 2,
  76. transparent: true,
  77. opacity: 0.4
  78. });
  79. lineMaterial.depthTest = false;
  80. let edge = new THREE.Line(lineGeometry, lineMaterial);
  81. edge.visible = false;
  82. this.add(edge);
  83. this.edges.push(edge);
  84. let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
  85. let boxMaterial = new THREE.MeshBasicMaterial({color: 0xff0000, transparent: true, opacity: 0.2});
  86. let box = new THREE.Mesh(boxGeometry, boxMaterial);
  87. box.visible = false;
  88. this.add(box);
  89. this.boxes.push(box);
  90. }
  91. { // event listeners
  92. let drag = (e) => {
  93. let I = Utils.getMousePointCloudIntersection(
  94. e.drag.end,
  95. e.viewer.scene.getActiveCamera(),
  96. e.viewer,
  97. e.viewer.scene.pointclouds);
  98. if (I) {
  99. let i = this.spheres.indexOf(e.drag.object);
  100. if (i !== -1) {
  101. this.setPosition(i, I.location);
  102. //this.dispatchEvent({
  103. // 'type': 'marker_moved',
  104. // 'profile': this,
  105. // 'index': i
  106. //});
  107. }
  108. }
  109. };
  110. let drop = e => {
  111. let i = this.spheres.indexOf(e.drag.object);
  112. if (i !== -1) {
  113. this.dispatchEvent({
  114. 'type': 'marker_dropped',
  115. 'profile': this,
  116. 'index': i
  117. });
  118. }
  119. };
  120. let mouseover = (e) => e.object.material.emissive.setHex(0x888888);
  121. let mouseleave = (e) => e.object.material.emissive.setHex(0x000000);
  122. sphere.addEventListener('drag', drag);
  123. sphere.addEventListener('drop', drop);
  124. sphere.addEventListener('mouseover', mouseover);
  125. sphere.addEventListener('mouseleave', mouseleave);
  126. }
  127. let event = {
  128. type: 'marker_added',
  129. profile: this,
  130. sphere: sphere
  131. };
  132. this.dispatchEvent(event);
  133. this.setPosition(this.points.length - 1, point);
  134. }
  135. removeMarker (index) {
  136. this.points.splice(index, 1);
  137. this.remove(this.spheres[index]);
  138. let edgeIndex = (index === 0) ? 0 : (index - 1);
  139. this.remove(this.edges[edgeIndex]);
  140. this.edges.splice(edgeIndex, 1);
  141. this.remove(this.boxes[edgeIndex]);
  142. this.boxes.splice(edgeIndex, 1);
  143. this.spheres.splice(index, 1);
  144. this.update();
  145. this.dispatchEvent({
  146. 'type': 'marker_removed',
  147. 'profile': this
  148. });
  149. }
  150. setPosition (index, position) {
  151. let point = this.points[index];
  152. point.copy(position);
  153. let event = {
  154. type: 'marker_moved',
  155. profile: this,
  156. index: index,
  157. position: point.clone()
  158. };
  159. this.dispatchEvent(event);
  160. this.update();
  161. }
  162. setWidth (width) {
  163. this.width = width;
  164. let event = {
  165. type: 'width_changed',
  166. profile: this,
  167. width: width
  168. };
  169. this.dispatchEvent(event);
  170. this.update();
  171. }
  172. getWidth () {
  173. return this.width;
  174. }
  175. update () {
  176. if (this.points.length === 0) {
  177. return;
  178. } else if (this.points.length === 1) {
  179. let point = this.points[0];
  180. this.spheres[0].position.copy(point);
  181. return;
  182. }
  183. let min = this.points[0].clone();
  184. let max = this.points[0].clone();
  185. let centroid = new THREE.Vector3();
  186. let lastIndex = this.points.length - 1;
  187. for (let i = 0; i <= lastIndex; i++) {
  188. let point = this.points[i];
  189. let sphere = this.spheres[i];
  190. let leftIndex = (i === 0) ? lastIndex : i - 1;
  191. // let rightIndex = (i === lastIndex) ? 0 : i + 1;
  192. let leftVertex = this.points[leftIndex];
  193. // let rightVertex = this.points[rightIndex];
  194. let leftEdge = this.edges[leftIndex];
  195. let rightEdge = this.edges[i];
  196. let leftBox = this.boxes[leftIndex];
  197. // rightBox = this.boxes[i];
  198. // let leftEdgeLength = point.distanceTo(leftVertex);
  199. // let rightEdgeLength = point.distanceTo(rightVertex);
  200. // let leftEdgeCenter = new THREE.Vector3().addVectors(leftVertex, point).multiplyScalar(0.5);
  201. // let rightEdgeCenter = new THREE.Vector3().addVectors(point, rightVertex).multiplyScalar(0.5);
  202. sphere.position.copy(point);
  203. if (this._modifiable) {
  204. sphere.visible = true;
  205. } else {
  206. sphere.visible = false;
  207. }
  208. if (leftEdge) {
  209. leftEdge.geometry.vertices[1].copy(point);
  210. leftEdge.geometry.verticesNeedUpdate = true;
  211. leftEdge.geometry.computeBoundingSphere();
  212. }
  213. if (rightEdge) {
  214. rightEdge.geometry.vertices[0].copy(point);
  215. rightEdge.geometry.verticesNeedUpdate = true;
  216. rightEdge.geometry.computeBoundingSphere();
  217. }
  218. if (leftBox) {
  219. let start = leftVertex;
  220. let end = point;
  221. let length
  222. if(window.axisYup){
  223. length = start.clone().setY(0).distanceTo(end.clone().setY(0));
  224. }else{
  225. length = start.clone().setZ(0).distanceTo(end.clone().setZ(0));
  226. leftBox.up.set(0, 0, 1);
  227. }
  228. leftBox.scale.set(length, 1000000, this.width);
  229. let center = new THREE.Vector3().addVectors(start, end).multiplyScalar(0.5);
  230. let diff = new THREE.Vector3().subVectors(end, start);
  231. let target = new THREE.Vector3(diff.y, -diff.x, 0);
  232. leftBox.position.set(0, 0, 0);
  233. leftBox.lookAt(target);
  234. leftBox.position.copy(center);
  235. }
  236. centroid.add(point);
  237. min.min(point);
  238. max.max(point);
  239. }
  240. centroid.multiplyScalar(1 / this.points.length);
  241. for (let i = 0; i < this.boxes.length; i++) {
  242. let box = this.boxes[i];
  243. box.position.z = min.z + (max.z - min.z) / 2;
  244. }
  245. }
  246. raycast (raycaster, intersects) {
  247. for (let i = 0; i < this.points.length; i++) {
  248. let sphere = this.spheres[i];
  249. sphere.raycast(raycaster, intersects);
  250. }
  251. // recalculate distances because they are not necessarely correct
  252. // for scaled objects.
  253. // see https://github.com/mrdoob/three.js/issues/5827
  254. // TODO: remove this once the bug has been fixed
  255. for (let i = 0; i < intersects.length; i++) {
  256. let I = intersects[i];
  257. I.distance = raycaster.ray.origin.distanceTo(I.point);
  258. }
  259. intersects.sort(function (a, b) { return a.distance - b.distance; });
  260. };
  261. get modifiable () {
  262. return this._modifiable;
  263. }
  264. set modifiable (value) {
  265. this._modifiable = value;
  266. this.update();
  267. }
  268. }