|
@@ -4,7 +4,7 @@
|
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
|
*/
|
|
|
|
|
|
-import { BehaviorSubject } from 'rxjs';
|
|
|
+import { BehaviorSubject, Subscription } from 'rxjs';
|
|
|
|
|
|
import { Vec3, Mat4, EPSILON } from 'mol-math/linear-algebra'
|
|
|
import InputObserver from 'mol-util/input/input-observer'
|
|
@@ -38,11 +38,11 @@ interface Canvas3D {
|
|
|
|
|
|
center: (p: Vec3) => void
|
|
|
|
|
|
- hide: (repr: Representation<any>) => void
|
|
|
- show: (repr: Representation<any>) => void
|
|
|
+ hide: (repr: Representation.Any) => void
|
|
|
+ show: (repr: Representation.Any) => void
|
|
|
|
|
|
- add: (repr: Representation<any>) => void
|
|
|
- remove: (repr: Representation<any>) => void
|
|
|
+ add: (repr: Representation.Any) => void
|
|
|
+ remove: (repr: Representation.Any) => void
|
|
|
update: () => void
|
|
|
clear: () => void
|
|
|
|
|
@@ -52,7 +52,7 @@ interface Canvas3D {
|
|
|
pick: () => void
|
|
|
identify: (x: number, y: number) => Promise<PickingId | undefined>
|
|
|
mark: (loci: Loci, action: MarkerAction) => void
|
|
|
- getLoci: (pickingId: PickingId) => { loci: Loci, repr?: Representation<any> }
|
|
|
+ getLoci: (pickingId: PickingId) => { loci: Loci, repr?: Representation.Any }
|
|
|
|
|
|
readonly reprCount: BehaviorSubject<number>
|
|
|
readonly identified: BehaviorSubject<string>
|
|
@@ -76,7 +76,8 @@ namespace Canvas3D {
|
|
|
export function create(canvas: HTMLCanvasElement, container: Element, props: Partial<Canvas3DProps> = {}): Canvas3D {
|
|
|
const p = { ...props, ...DefaultCanvas3DProps }
|
|
|
|
|
|
- const reprMap = new Map<Representation<any>, Set<RenderObject>>()
|
|
|
+ const reprRenderObjects = new Map<Representation.Any, Set<RenderObject>>()
|
|
|
+ const reprUpdatedSubscriptions = new Map<Representation.Any, Subscription>()
|
|
|
const reprCount = new BehaviorSubject(0)
|
|
|
const identified = new BehaviorSubject('')
|
|
|
|
|
@@ -123,7 +124,7 @@ namespace Canvas3D {
|
|
|
function getLoci(pickingId: PickingId) {
|
|
|
let loci: Loci = EmptyLoci
|
|
|
let repr: Representation.Any = Representation.Empty
|
|
|
- reprMap.forEach((_, _repr) => {
|
|
|
+ reprRenderObjects.forEach((_, _repr) => {
|
|
|
const _loci = _repr.getLoci(pickingId)
|
|
|
if (!isEmptyLoci(_loci)) {
|
|
|
if (!isEmptyLoci(loci)) console.warn('found another loci')
|
|
@@ -136,7 +137,7 @@ namespace Canvas3D {
|
|
|
|
|
|
function mark(loci: Loci, action: MarkerAction) {
|
|
|
let changed = false
|
|
|
- reprMap.forEach((roSet, repr) => {
|
|
|
+ reprRenderObjects.forEach((roSet, repr) => {
|
|
|
changed = repr.mark(loci, action) || changed
|
|
|
})
|
|
|
if (changed) {
|
|
@@ -268,6 +269,23 @@ namespace Canvas3D {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ function add(repr: Representation.Any) {
|
|
|
+ const oldRO = reprRenderObjects.get(repr)
|
|
|
+ const newRO = new Set<RenderObject>()
|
|
|
+ repr.renderObjects.forEach(o => newRO.add(o))
|
|
|
+ if (oldRO) {
|
|
|
+ SetUtils.difference(newRO, oldRO).forEach(o => scene.add(o))
|
|
|
+ SetUtils.difference(oldRO, newRO).forEach(o => scene.remove(o))
|
|
|
+ scene.update()
|
|
|
+ } else {
|
|
|
+ repr.renderObjects.forEach(o => scene.add(o))
|
|
|
+ }
|
|
|
+ reprRenderObjects.set(repr, newRO)
|
|
|
+ reprCount.next(reprRenderObjects.size)
|
|
|
+ scene.update()
|
|
|
+ requestDraw(true)
|
|
|
+ }
|
|
|
+
|
|
|
handleResize()
|
|
|
|
|
|
return {
|
|
@@ -278,42 +296,35 @@ namespace Canvas3D {
|
|
|
Vec3.set(camera.target, p[0], p[1], p[2])
|
|
|
},
|
|
|
|
|
|
- hide: (repr: Representation<any>) => {
|
|
|
- const renderObjectSet = reprMap.get(repr)
|
|
|
+ hide: (repr: Representation.Any) => {
|
|
|
+ const renderObjectSet = reprRenderObjects.get(repr)
|
|
|
if (renderObjectSet) renderObjectSet.forEach(o => o.state.visible = false)
|
|
|
},
|
|
|
- show: (repr: Representation<any>) => {
|
|
|
- const renderObjectSet = reprMap.get(repr)
|
|
|
+ show: (repr: Representation.Any) => {
|
|
|
+ const renderObjectSet = reprRenderObjects.get(repr)
|
|
|
if (renderObjectSet) renderObjectSet.forEach(o => o.state.visible = true)
|
|
|
},
|
|
|
|
|
|
- add: (repr: Representation<any>) => {
|
|
|
- const oldRO = reprMap.get(repr)
|
|
|
- const newRO = new Set<RenderObject>()
|
|
|
- repr.renderObjects.forEach(o => newRO.add(o))
|
|
|
- if (oldRO) {
|
|
|
- SetUtils.difference(newRO, oldRO).forEach(o => scene.add(o))
|
|
|
- SetUtils.difference(oldRO, newRO).forEach(o => scene.remove(o))
|
|
|
- scene.update()
|
|
|
- } else {
|
|
|
- repr.renderObjects.forEach(o => scene.add(o))
|
|
|
- }
|
|
|
- reprMap.set(repr, newRO)
|
|
|
- reprCount.next(reprMap.size)
|
|
|
- scene.update()
|
|
|
+ add: (repr: Representation.Any) => {
|
|
|
+ add(repr)
|
|
|
+ reprUpdatedSubscriptions.set(repr, repr.updated.subscribe(_ => add(repr)))
|
|
|
},
|
|
|
- remove: (repr: Representation<any>) => {
|
|
|
- const renderObjectSet = reprMap.get(repr)
|
|
|
- if (renderObjectSet) {
|
|
|
- renderObjectSet.forEach(o => scene.remove(o))
|
|
|
- reprMap.delete(repr)
|
|
|
- reprCount.next(reprMap.size)
|
|
|
+ remove: (repr: Representation.Any) => {
|
|
|
+ const updatedSubscription = reprUpdatedSubscriptions.get(repr)
|
|
|
+ if (updatedSubscription) {
|
|
|
+ updatedSubscription.unsubscribe()
|
|
|
+ }
|
|
|
+ const renderObjects = reprRenderObjects.get(repr)
|
|
|
+ if (renderObjects) {
|
|
|
+ renderObjects.forEach(o => scene.remove(o))
|
|
|
+ reprRenderObjects.delete(repr)
|
|
|
+ reprCount.next(reprRenderObjects.size)
|
|
|
scene.update()
|
|
|
}
|
|
|
},
|
|
|
update: () => scene.update(),
|
|
|
clear: () => {
|
|
|
- reprMap.clear()
|
|
|
+ reprRenderObjects.clear()
|
|
|
scene.clear()
|
|
|
},
|
|
|
|