threepipe
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

bbox.ts 3.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import {Box2, BufferAttribute, Camera, InterleavedBufferAttribute, Mesh, Object3D, Vector2, Vector3} from 'three'
  2. export function computeScreenSpaceBoundingBox(obj: Object3D, camera: Camera) {
  3. let min: Vector2|undefined
  4. let max: Vector2|undefined
  5. // Is this an array of objects?
  6. if (Array.isArray(obj)) {
  7. for (const oo of obj) {
  8. const box2 = computeScreenSpaceBoundingBox(oo, camera)
  9. if (min === undefined || max === undefined) {
  10. min = box2.min.clone()
  11. max = box2.max.clone()
  12. } else {
  13. min.min(box2.min)
  14. max.max(box2.max)
  15. }
  16. }
  17. }
  18. // Does this object have geometry?
  19. const mesh = obj as Mesh
  20. if (mesh.geometry !== undefined) {
  21. const vertices = (mesh.geometry as any).vertices // legacy Geometry support
  22. if (vertices === undefined
  23. && mesh.geometry.attributes !== undefined
  24. && 'position' in mesh.geometry.attributes) {
  25. // Buffered geometry
  26. const vertex = new Vector3()
  27. const pos = mesh.geometry.attributes.position as any as BufferAttribute | InterleavedBufferAttribute
  28. for (let i = 0; i < pos.count * pos.itemSize; i += pos.itemSize) {
  29. vertex.set(pos.array[i], pos.array[i + 1], pos.array[1 + 2])
  30. const vertexWorldCoord = vertex.applyMatrix4(obj.matrixWorld)
  31. const vertexScreenSpace = vertexWorldCoord.project(camera)
  32. const vertexScreenSpaced = new Vector2(vertexScreenSpace.x, vertexScreenSpace.y)
  33. if (min === undefined || max === undefined) {
  34. min = vertexScreenSpaced.clone()
  35. max = vertexScreenSpaced.clone()
  36. } else {
  37. min.min(vertexScreenSpaced)
  38. max.max(vertexScreenSpaced)
  39. }
  40. }
  41. } else {
  42. // legacy Geometry support
  43. for (const vertex of vertices) {
  44. const vertexWorldCoord = vertex.clone().applyMatrix4(obj.matrixWorld)
  45. const vertexScreenSpace = vertexWorldCoord.project(camera)
  46. const vertexScreenSpaced = new Vector2(vertexScreenSpace.x, vertexScreenSpace.y)
  47. if (min === undefined || max === undefined) {
  48. min = vertexScreenSpaced.clone()
  49. max = vertexScreenSpaced.clone()
  50. } else {
  51. min.min(vertexScreenSpaced)
  52. max.max(vertexScreenSpaced)
  53. }
  54. }
  55. }
  56. }
  57. // Does this object have children?
  58. if (obj.children !== undefined) {
  59. for (const oo of obj.children) {
  60. const box2 = computeScreenSpaceBoundingBox(oo, camera)
  61. if (min === undefined || max === undefined) {
  62. min = box2.min.clone()
  63. max = box2.max.clone()
  64. } else {
  65. min.min(box2.min)
  66. max.max(box2.max)
  67. }
  68. }
  69. }
  70. return new Box2(min, max)
  71. }