Skip to content

Commit

Permalink
fix: do not uncache spatial on reference change
Browse files Browse the repository at this point in the history
Uncaching on reference change leads to a race condition
if the browser has internally cached files that are to
be fetched. If cells happen to be cached before the
reference change is invoked, those cells will be disposed.

Reference change should only occur on cell change.
  • Loading branch information
oscarlorentzon committed Jan 30, 2022
1 parent 7dca018 commit f2f49ec
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 16 deletions.
21 changes: 21 additions & 0 deletions src/component/spatial/SpatialCommon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { LngLatAlt } from "../../api/interfaces/LngLatAlt";
import { enuToGeodetic, geodeticToEnu } from "../../geo/GeoCoords";

export function resetEnu(reference: LngLatAlt, prevEnu: number[], prevReference: LngLatAlt): number[] {
const [prevX, prevY, prevZ] = prevEnu;
const [lng, lat, alt] = enuToGeodetic(
prevX,
prevY,
prevZ,
prevReference.lng,
prevReference.lat,
prevReference.alt);

return geodeticToEnu(
lng,
lat,
alt,
reference.lng,
reference.lat,
reference.alt);
}
15 changes: 11 additions & 4 deletions src/component/spatial/SpatialComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
take,
withLatestFrom,
filter,
pairwise,
} from "rxjs/operators";

import { Image } from "../../graph/Image";
Expand Down Expand Up @@ -149,9 +150,13 @@ export class SpatialComponent extends Component<SpatialConfiguration> {
const subs = this._subscriptions;

subs.push(this._navigator.stateService.reference$
.subscribe((): void => {
this._scene.uncache();
}));
.pipe(
pairwise())
.subscribe(
([prevReference, reference]: [LngLatAlt, LngLatAlt]): void => {
this._scene.resetReference(reference, prevReference);
}
));

subs.push(this._navigator.graphService.filter$
.subscribe(imageFilter => { this._scene.setFilter(imageFilter); }));
Expand Down Expand Up @@ -268,7 +273,9 @@ export class SpatialComponent extends Component<SpatialConfiguration> {
map((images: Image[]) => ({ id: cellId, images })));
},
6));
}));
}),
publishReplay(1),
refCount());

subs.push(cell$.pipe(
withLatestFrom(this._navigator.stateService.reference$))
Expand Down
54 changes: 47 additions & 7 deletions src/component/spatial/SpatialScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { SpatialCell } from "./scene/SpatialCell";
import { SpatialAssets } from "./scene/SpatialAssets";
import { isModeVisible } from "./Modes";
import { PointVisualizationMode } from "./enums/PointVisualizationMode";
import { LngLatAlt } from "../../api/interfaces/LngLatAlt";
import { resetEnu } from "./SpatialCommon";

const NO_CLUSTER_ID = "NO_CLUSTER_ID";
const NO_MERGE_ID = "NO_MERGE_ID";
Expand Down Expand Up @@ -250,6 +252,51 @@ export class SpatialScene {
this._images[cellId].hasImage(imageId);
}

public render(
camera: PerspectiveCamera,
renderer: WebGLRenderer): void {
renderer.render(this._scene, camera);
this._needsRender = false;
}

public resetReference(
reference: LngLatAlt,
prevReference: LngLatAlt)
: void {
const clusters = this._clusters;
for (const clusterId in clusters) {
if (!clusters.hasOwnProperty(clusterId)) {
continue;
}
const cluster = clusters[clusterId];
cluster.points.position.fromArray(resetEnu(
reference,
cluster.points.position.toArray(),
prevReference));
}

const cells = this._cells;
for (const cellId in cells) {
if (!cells.hasOwnProperty(cellId)) {
continue;
}
const cell = cells[cellId];
cell.position.fromArray(resetEnu(
reference,
cell.position.toArray(),
prevReference));
}

const images = this._images;
for (const cellId in images) {
if (!images.hasOwnProperty(cellId)) {
continue;
}
const spatialCell = images[cellId];
spatialCell.resetReference(reference, prevReference);
}
}

public setCameraSize(cameraSize: number): void {
if (Math.abs(cameraSize - this._cameraSize) < 1e-3) { return; }

Expand Down Expand Up @@ -435,13 +482,6 @@ export class SpatialScene {
this._needsRender = true;
}

public render(
camera: PerspectiveCamera,
renderer: WebGLRenderer): void {
renderer.render(this._scene, camera);
this._needsRender = false;
}

public uncache(keepCellIds?: string[]): void {
for (const cellId of Object.keys(this._cellClusters)) {
if (!!keepCellIds && keepCellIds.indexOf(cellId) !== -1) {
Expand Down
41 changes: 36 additions & 5 deletions src/component/spatial/scene/SpatialCell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { CameraVisualizationMode } from "../enums/CameraVisualizationMode";
import { isSpherical } from "../../../geo/Geo";
import { SphericalCameraFrame } from "./SphericalCameraFrame";
import { PerspectiveCameraFrame } from "./PerspectiveCameraFrame";
import { LngLatAlt } from "../../../api/interfaces/LngLatAlt";
import { resetEnu } from "../SpatialCommon";

type ColorIdCamerasMap = Map<string, CameraFrameBase[]>;

Expand Down Expand Up @@ -42,19 +44,19 @@ type ImageVisualizationProps = {
export class SpatialCell {
public readonly cameras: Object3D;
public readonly keys: string[];
public clusterVisibles: { [key: string]: boolean };
public clusterVisibles: { [key: string]: boolean; };

private readonly _positions: Object3D;
private readonly _positionLines: { [key: string]: PositionLine };
private readonly _cameraFrames: { [key: string]: CameraFrameBase };
private readonly _positionLines: { [key: string]: PositionLine; };
private readonly _cameraFrames: { [key: string]: CameraFrameBase; };
private readonly _clusters: ColorIdCamerasMap;
private readonly _connectedComponents: ColorIdCamerasMap;
private readonly _sequences: ColorIdCamerasMap;
private readonly _props: {
[id: string]: {
image: Image,
ids: ImageIdMap,
}
};
};

private _frameMaterial: LineBasicMaterial;
Expand Down Expand Up @@ -167,7 +169,7 @@ export class SpatialCell {
return this._sequences;
}
const cvm = CameraVisualizationMode;
const defaultId = cvm[cvm.Homogeneous]
const defaultId = cvm[cvm.Homogeneous];
const cameras = <ColorIdCamerasMap>new Map();
cameras.set(defaultId, <CameraFrameBase[]>this.cameras.children);
return cameras;
Expand All @@ -192,6 +194,35 @@ export class SpatialCell {
return this.keys.indexOf(key) !== -1;
}

public resetReference(
reference: LngLatAlt,
prevReference: LngLatAlt)
: void {
const frames = this._cameraFrames;
for (const frameId in frames) {
if (!frames.hasOwnProperty(frameId)) {
continue;
}
const frame = frames[frameId];
frame.position.fromArray(resetEnu(
reference,
frame.position.toArray(),
prevReference));
}

const lines = this._positionLines;
for (const lineId in lines) {
if (!lines.hasOwnProperty(lineId)) {
continue;
}
const line = lines[lineId];
line.position.fromArray(resetEnu(
reference,
line.position.toArray(),
prevReference));
}
}

public visualize(props: ImageVisualizationProps): void {
const id = props.id;
const visible = props.visible;
Expand Down

0 comments on commit f2f49ec

Please sign in to comment.