scene.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Renderable } from './renderable'
  7. import { WebGLContext } from './webgl/context';
  8. import { RenderableValues, BaseValues } from './renderable/schema';
  9. import { RenderObject, createRenderable } from './render-object';
  10. import { Object3D } from './object3d';
  11. import { Sphere3D } from 'mol-math/geometry';
  12. import { Vec3 } from 'mol-math/linear-algebra';
  13. function calculateBoundingSphere(renderableMap: Map<RenderObject, Renderable<RenderableValues & BaseValues>>): Sphere3D {
  14. let count = 0
  15. const center = Vec3.zero()
  16. renderableMap.forEach(r => {
  17. if (r.boundingSphere.radius) {
  18. Vec3.add(center, center, r.boundingSphere.center)
  19. ++count
  20. }
  21. })
  22. if (count > 0) {
  23. Vec3.scale(center, center, 1 / count)
  24. }
  25. let radius = 0
  26. renderableMap.forEach(r => {
  27. if (r.boundingSphere.radius) {
  28. radius = Math.max(radius, Vec3.distance(center, r.boundingSphere.center) + r.boundingSphere.radius)
  29. }
  30. })
  31. return { center, radius };
  32. }
  33. interface Scene extends Object3D {
  34. readonly count: number
  35. readonly boundingSphere: Sphere3D
  36. update: () => void
  37. add: (o: RenderObject) => void
  38. remove: (o: RenderObject) => void
  39. clear: () => void
  40. forEach: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void
  41. eachOpaque: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void
  42. eachTransparent: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void
  43. }
  44. namespace Scene {
  45. export function create(ctx: WebGLContext): Scene {
  46. const renderableMap = new Map<RenderObject, Renderable<RenderableValues & BaseValues>>()
  47. let boundingSphere: Sphere3D | undefined
  48. const object3d = Object3D.create()
  49. return {
  50. get view () { return object3d.view },
  51. get position () { return object3d.position },
  52. get direction () { return object3d.direction },
  53. get up () { return object3d.up },
  54. update: () => {
  55. Object3D.update(object3d)
  56. renderableMap.forEach(r => r.update())
  57. boundingSphere = undefined
  58. },
  59. add: (o: RenderObject) => {
  60. if (!renderableMap.has(o)) {
  61. renderableMap.set(o, createRenderable(ctx, o))
  62. boundingSphere = undefined
  63. } else {
  64. console.warn(`RenderObject with id '${o.id}' already present`)
  65. }
  66. },
  67. remove: (o: RenderObject) => {
  68. const renderable = renderableMap.get(o)
  69. if (renderable) {
  70. renderable.dispose()
  71. renderableMap.delete(o)
  72. boundingSphere = undefined
  73. }
  74. },
  75. clear: () => {
  76. renderableMap.forEach(renderable => renderable.dispose())
  77. renderableMap.clear()
  78. boundingSphere = undefined
  79. },
  80. forEach: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
  81. renderableMap.forEach(callbackFn)
  82. },
  83. eachOpaque: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
  84. renderableMap.forEach((r, o) => {
  85. if (r.opaque) callbackFn(r, o)
  86. })
  87. },
  88. eachTransparent: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => {
  89. renderableMap.forEach((r, o) => {
  90. if (!r.opaque) callbackFn(r, o)
  91. })
  92. },
  93. get count() {
  94. return renderableMap.size
  95. },
  96. get boundingSphere() {
  97. if (boundingSphere) return boundingSphere
  98. // TODO avoid object creation
  99. boundingSphere = calculateBoundingSphere(renderableMap)
  100. return boundingSphere
  101. }
  102. }
  103. }
  104. }
  105. export default Scene