box3d.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  6. */
  7. import { Vec3, Mat4 } from '../../linear-algebra'
  8. import { PositionData } from '../common'
  9. import { OrderedSet } from 'mol-data/int';
  10. interface Box3D { min: Vec3, max: Vec3 }
  11. namespace Box3D {
  12. export function create(min: Vec3, max: Vec3): Box3D { return { min, max }; }
  13. export function empty(): Box3D { return { min: Vec3.zero(), max: Vec3.zero() }; }
  14. export function computeBounding(data: PositionData): Box3D {
  15. const min = Vec3.create(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
  16. const max = Vec3.create(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
  17. const { x, y, z, indices } = data;
  18. for (let t = 0, _t = OrderedSet.size(indices); t < _t; t++) {
  19. const i = OrderedSet.getAt(indices, t);
  20. min[0] = Math.min(x[i], min[0]);
  21. min[1] = Math.min(y[i], min[1]);
  22. min[2] = Math.min(z[i], min[2]);
  23. max[0] = Math.max(x[i], max[0]);
  24. max[1] = Math.max(y[i], max[1]);
  25. max[2] = Math.max(z[i], max[2]);
  26. }
  27. return { min, max }
  28. }
  29. /** Get size of the box */
  30. export function size(size: Vec3, box: Box3D): Vec3 {
  31. return Vec3.sub(size, box.max, box.min);
  32. }
  33. export function setEmpty(box: Box3D): Box3D {
  34. Vec3.set(box.min, Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)
  35. Vec3.set(box.max, -Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE)
  36. return box
  37. }
  38. /** Add point to box */
  39. export function add(box: Box3D, point: Vec3): Box3D {
  40. Vec3.min(box.min, box.min, point)
  41. Vec3.max(box.max, box.max, point)
  42. return box
  43. }
  44. /** Expand box by delta */
  45. export function expand(out: Box3D, box: Box3D, delta: Vec3): Box3D {
  46. Vec3.sub(out.min, box.min, delta)
  47. Vec3.add(out.max, box.max, delta)
  48. return out
  49. }
  50. const tmpTransformV = Vec3.zero()
  51. /** Transform box with a Mat4 */
  52. export function transform(out: Box3D, box: Box3D, m: Mat4): Box3D {
  53. const [ minX, minY, minZ ] = box.min
  54. const [ maxX, maxY, maxZ ] = box.max
  55. setEmpty(out)
  56. add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, minY, minZ), m))
  57. add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, minY, maxZ), m))
  58. add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, maxY, minZ), m))
  59. add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, maxY, maxZ), m))
  60. add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, maxX, minY, minZ), m))
  61. add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, maxX, minY, maxZ), m))
  62. add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, maxX, maxY, minZ), m))
  63. add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, maxX, maxY, maxZ), m))
  64. return out
  65. }
  66. }
  67. export { Box3D }