Profile.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /**
  2. * Profile.js
  3. *
  4. * @author realor
  5. */
  6. import { Formula } from '../formula/Formula.js'
  7. import { ProfileGeometry } from './ProfileGeometry.js'
  8. import * as THREE from '../lib/three.module.js'
  9. class Profile extends THREE.LineSegments {
  10. /* a Profile is an Object3D that represents the outline of a 2D path */
  11. static ProfileMaterial = new THREE.LineBasicMaterial({
  12. name: 'ProfileMaterial',
  13. color: 0x0,
  14. opacity: 0.8,
  15. linewidth: 1.5,
  16. transparent: true
  17. })
  18. constructor(profileGeometry, material = Profile.ProfileMaterial) {
  19. super(profileGeometry, material)
  20. this.type = 'Profile'
  21. this.builder = null
  22. }
  23. raycast(raycaster, intersects) {
  24. const geometry = this.geometry
  25. if (this.visible && geometry instanceof ProfileGeometry) {
  26. const threshold = raycaster.params.Line.threshold
  27. const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3)
  28. const localThresholdSq = localThreshold * localThreshold
  29. const path = geometry.path
  30. const matrixWorld = this.matrixWorld
  31. const points = path.getPoints(geometry.divisions)
  32. const point1 = new THREE.Vector3()
  33. const point2 = new THREE.Vector3()
  34. const interRay = new THREE.Vector3()
  35. const interSegment = new THREE.Vector3()
  36. const localRay = new THREE.Ray()
  37. const inverseMatrixWorld = new THREE.Matrix4()
  38. inverseMatrixWorld.copy(matrixWorld).invert()
  39. localRay.copy(raycaster.ray).applyMatrix4(inverseMatrixWorld)
  40. for (let i = 0; i < points.length; i++) {
  41. let j = (i + 1) % points.length
  42. point1.set(points[i].x, points[i].y, 0)
  43. point2.set(points[j].x, points[j].y, 0)
  44. const distSq = localRay.distanceSqToSegment(point1, point2, interRay, interSegment)
  45. if (distSq < localThresholdSq) {
  46. interRay.applyMatrix4(matrixWorld) // to world
  47. const distance = raycaster.ray.origin.distanceTo(interRay)
  48. intersects.push({
  49. distance: distance,
  50. object: this,
  51. point: interRay.clone().applyMatrix4(matrixWorld) // to world
  52. })
  53. }
  54. }
  55. }
  56. }
  57. updateGeometry(geometry) {
  58. if (this.geometry) this.geometry.dispose()
  59. this.geometry = geometry
  60. }
  61. copy(source) {
  62. super.copy(source)
  63. this.material = source.material
  64. this.geometry = source.geometry
  65. this.builder = source.builder ? source.builder.clone() : null
  66. Formula.copy(this, source)
  67. return this
  68. }
  69. }
  70. export { Profile }