Skip to content

Commit

Permalink
feat: use geometry to avoid reference reset
Browse files Browse the repository at this point in the history
When larger tile sizes are used the reference
should not be reset if it is within the original
grid.
  • Loading branch information
oscarlorentzon committed Oct 16, 2024
1 parent 23349c4 commit e39ca9c
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 34 deletions.
3 changes: 3 additions & 0 deletions src/state/StateContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import { Transform } from "../geo/Transform";
import { LngLatAlt } from "../api/interfaces/LngLatAlt";
import { Image } from "../graph/Image";
import { StateTransitionMatrix } from "./StateTransitionMatrix";
import { IGeometryProvider } from "../api/interfaces/IGeometryProvider";

export class StateContext implements IStateContext {
private _state: StateBase;
private _transitions: StateTransitionMatrix;

constructor(
state: State,
geometry: IGeometryProvider,
transitionMode?: TransitionMode) {
this._transitions = new StateTransitionMatrix();
this._state = this._transitions.generate(
Expand All @@ -24,6 +26,7 @@ export class StateContext implements IStateContext {
alpha: 1,
camera: new Camera(),
currentIndex: -1,
geometry,
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: transitionMode == null ? TransitionMode.Default : transitionMode,
Expand Down
4 changes: 3 additions & 1 deletion src/state/StateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { Transform } from "../geo/Transform";
import { LngLatAlt } from "../api/interfaces/LngLatAlt";
import { SubscriptionHolder } from "../util/SubscriptionHolder";
import { Clock } from "three";
import { IGeometryProvider } from "../api/interfaces/IGeometryProvider";

interface IContextOperation {
(context: IStateContext): IStateContext;
Expand Down Expand Up @@ -73,6 +74,7 @@ export class StateService {

constructor(
initialState: State,
geometry: IGeometryProvider,
transitionMode?: TransitionMode) {

const subs = this._subscriptions;
Expand All @@ -90,7 +92,7 @@ export class StateService {
(context: IStateContext, operation: IContextOperation): IStateContext => {
return operation(context);
},
new StateContext(initialState, transitionMode)),
new StateContext(initialState, geometry, transitionMode)),
publishReplay(1),
refCount());

Expand Down
2 changes: 2 additions & 0 deletions src/state/interfaces/IStateBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { Camera } from "../../geo/Camera";
import { LngLatAlt } from "../../api/interfaces/LngLatAlt";
import { TransitionMode } from "../TransitionMode";
import { Image } from "../../graph/Image";
import { IGeometryProvider } from "../../mapillary";

export interface IStateBase {
alpha: number;
camera: Camera;
currentIndex: number;
geometry: IGeometryProvider,
reference: LngLatAlt;
trajectory: Image[];
transitionMode: TransitionMode;
Expand Down
22 changes: 21 additions & 1 deletion src/state/state/StateBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import { Spatial } from "../../geo/Spatial";
import { Transform } from "../../geo/Transform";
import { LngLatAlt } from "../../api/interfaces/LngLatAlt";
import { Image } from "../../graph/Image";
import { IGeometryProvider } from "../../mapillary";
import { connectedComponent } from "../../api/CellMath";

export abstract class StateBase implements IStateBase {
protected _spatial: Spatial;
protected _geometry: IGeometryProvider;

protected _reference: LngLatAlt;

Expand All @@ -35,17 +38,22 @@ export abstract class StateBase implements IStateBase {
protected _motionless: boolean;

private _referenceThreshold: number;
private _referenceCellIds: Set<string>;
private _transitionThreshold: number;
private _transitionMode: TransitionMode;

constructor(state: IStateBase) {
this._spatial = new Spatial();
this._geometry = state.geometry;

this._referenceThreshold = 250;
this._transitionThreshold = 62.5;
this._transitionMode = state.transitionMode;

this._reference = state.reference;
this._referenceCellIds = new Set<string>(
connectedComponent(
this._geometry.lngLatToCellId(this._reference), 3, this._geometry));

this._alpha = state.alpha;
this._stateTransitionAlpha = 0;
Expand Down Expand Up @@ -107,6 +115,10 @@ export abstract class StateBase implements IStateBase {
return this._camera;
}

public get geometry(): IGeometryProvider {
return this._geometry;
}

public get zoom(): number {
return this._zoom;
}
Expand Down Expand Up @@ -327,11 +339,16 @@ export abstract class StateBase implements IStateBase {
reference.lng,
reference.lat);

// do not reset reference if image is within threshold distance
if (referenceDistance < this._referenceThreshold) {
return false;
}

// do not reset reference if image is within 7 x 7 grid of cells
const cellId = this._geometry.lngLatToCellId(currentImage.lngLat);
if (this._referenceCellIds.has(cellId)) {
return false;
}

if (previousImage != null) {
const transitionDistance = this._spatial.distanceFromLngLat(
currentImage.lngLat.lng,
Expand All @@ -353,6 +370,9 @@ export abstract class StateBase implements IStateBase {
this._reference.lat = currentImage.lngLat.lat;
this._reference.lng = currentImage.lngLat.lng;
this._reference.alt = currentImage.computedAltitude;
this._referenceCellIds = new Set<string>(
connectedComponent(
this._geometry.lngLatToCellId(this._reference), 3, this._geometry));

return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/viewer/Navigator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export class Navigator {
this._stateService = stateService ??
new StateService(
cameraControlsToState(cameraControls),
this._api.data.geometry,
options.transitionMode);

this._cacheService = cacheService ??
Expand Down
2 changes: 2 additions & 0 deletions test/helper/StateHelper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { S2GeometryProvider } from "../../src/api/S2GeometryProvider";
import { Camera } from "../../src/geo/Camera";
import { IAnimationState } from "../../src/state/interfaces/IAnimationState";
import { IStateBase } from "../../src/state/interfaces/IStateBase";
Expand Down Expand Up @@ -31,6 +32,7 @@ export function generateStateParams(): IStateBase {
alpha: 1,
camera: new Camera(),
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down
3 changes: 2 additions & 1 deletion test/state/StateService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ bootstrap();

import { StateService } from "../../src/state/StateService";
import { State } from "../../src/state/State";
import { S2GeometryProvider } from "../../src/api/S2GeometryProvider";

describe("StateService.ctor", () => {
it("should be contructed", () => {
let stateService: StateService = new StateService(State.Traversing);
let stateService: StateService = new StateService(State.Traversing, new S2GeometryProvider());

expect(stateService).toBeDefined();
});
Expand Down
2 changes: 2 additions & 0 deletions test/state/state/StateBase.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ProjectionService } from "../../../src/viewer/ProjectionService";
import { ImageCache } from "../../../src/graph/ImageCache";
import { DataProvider } from "../../helper/ProviderHelper";
import { TestImage } from "../../helper/TestImage";
import { S2GeometryProvider } from "../../../src/api/S2GeometryProvider";

class TestStateBase extends StateBase {
public traverse(): StateBase { return null; }
Expand Down Expand Up @@ -42,6 +43,7 @@ let createState: () => IStateBase = (): IStateBase => {
alpha: 1,
camera: new Camera(),
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down
7 changes: 7 additions & 0 deletions test/state/state/TraversingState.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import { ImageCache } from "../../../src/graph/ImageCache";
import { DataProvider } from "../../helper/ProviderHelper";
import { ProjectionService } from "../../../src/viewer/ProjectionService";
import { TestImage } from "../../helper/TestImage";
import { S2GeometryProvider } from "../../../src/api/S2GeometryProvider";

describe("TraversingState.ctor", () => {
it("should be defined", () => {
let state: IStateBase = {
alpha: 1,
camera: new Camera(),
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -72,6 +74,7 @@ describe("TraversingState.currentCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -106,6 +109,7 @@ describe("TraversingState.currentCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -148,6 +152,7 @@ describe("TraversingState.currentCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -204,6 +209,7 @@ describe("TraversingState.previousCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -238,6 +244,7 @@ describe("TraversingState.previousCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down
9 changes: 8 additions & 1 deletion test/state/state/WaitingState.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as THREE from "three";

import { ImageHelper } from "../../helper/ImageHelper";

import { Image } from "../../../src/graph/Image";
import { SpatialImageEnt } from "../../../src/api/ents/SpatialImageEnt";
import { IStateBase } from "../../../src/state/interfaces/IStateBase";
import { WaitingState } from "../../../src/state/state/WaitingState";
Expand All @@ -12,13 +11,15 @@ import { ImageCache } from "../../../src/graph/ImageCache";
import { DataProvider } from "../../helper/ProviderHelper";
import { ProjectionService } from "../../../src/viewer/ProjectionService";
import { TestImage } from "../../helper/TestImage";
import { S2GeometryProvider } from "../../../src/api/S2GeometryProvider";

describe("WaitingState.ctor", () => {
it("should be defined", () => {
let state: IStateBase = {
alpha: 1,
camera: new Camera(),
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -70,6 +71,7 @@ describe("WaitingState.currentCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -104,6 +106,7 @@ describe("WaitingState.currentCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -146,6 +149,7 @@ describe("WaitingState.currentCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -205,6 +209,7 @@ describe("WaitingState.previousCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -239,6 +244,7 @@ describe("WaitingState.previousCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down Expand Up @@ -279,6 +285,7 @@ describe("WaitingState.previousCamera.lookat", () => {
alpha: 1,
camera: camera,
currentIndex: -1,
geometry: new S2GeometryProvider(),
reference: { alt: 0, lat: 0, lng: 0 },
trajectory: [],
transitionMode: TransitionMode.Default,
Expand Down
16 changes: 8 additions & 8 deletions test/viewer/CacheService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ import { APIWrapper } from "../../src/api/APIWrapper";
import { Graph } from "../../src/graph/Graph";
import { GraphMode } from "../../src/graph/GraphMode";
import { GraphService } from "../../src/graph/GraphService";
import { IAnimationState } from "../../src/state/interfaces/IAnimationState";
import { AnimationFrame } from "../../src/state/interfaces/AnimationFrame";
import { State } from "../../src/state/State";
import { StateService } from "../../src/state/StateService";
import { CacheService } from "../../src/viewer/CacheService";
import { DataProvider } from "../helper/ProviderHelper";
import { createDefaultState } from "../helper/StateHelper";
import { StateServiceMockCreator } from "../helper/StateServiceMockCreator";
import { LngLatAlt } from "../../src/mapillary";
import { S2GeometryProvider } from "../../src/api/S2GeometryProvider";
import { LngLatAlt } from "../../src/api/interfaces/LngLatAlt";

describe("CacheService.ctor", () => {
it("should be defined when constructed", () => {
const api = new APIWrapper(new DataProvider());
const graphService = new GraphService(new Graph(api));
const stateService: StateService = new StateService(State.Traversing);
const stateService: StateService = new StateService(State.Traversing, new S2GeometryProvider());

const cacheService = new CacheService(graphService, stateService, api);

Expand All @@ -36,7 +36,7 @@ describe("CacheService.configure", () => {
it("should configure without errors", () => {
const api = new APIWrapper(new DataProvider());
const graphService = new GraphService(new Graph(api));
const stateService: StateService = new StateService(State.Traversing);
const stateService: StateService = new StateService(State.Traversing, new S2GeometryProvider());

const cacheService = new CacheService(graphService, stateService, api);

Expand All @@ -50,7 +50,7 @@ describe("CacheService.started", () => {
it("should not be started", () => {
const api = new APIWrapper(new DataProvider());
const graphService = new GraphService(new Graph(api));
const stateService: StateService = new StateService(State.Traversing);
const stateService: StateService = new StateService(State.Traversing, new S2GeometryProvider());

const cacheService = new CacheService(graphService, stateService, api);

Expand All @@ -60,7 +60,7 @@ describe("CacheService.started", () => {
it("should be started after calling start", () => {
const api = new APIWrapper(new DataProvider());
const graphService = new GraphService(new Graph(api));
const stateService: StateService = new StateService(State.Traversing);
const stateService: StateService = new StateService(State.Traversing, new S2GeometryProvider());

const cacheService = new CacheService(graphService, stateService, api);

Expand All @@ -72,7 +72,7 @@ describe("CacheService.started", () => {
it("should not be started after calling stop", () => {
const api = new APIWrapper(new DataProvider());
const graphService = new GraphService(new Graph(api));
const stateService: StateService = new StateService(State.Traversing);
const stateService: StateService = new StateService(State.Traversing, new S2GeometryProvider());

const cacheService = new CacheService(graphService, stateService, api);

Expand All @@ -87,7 +87,7 @@ class TestStateService extends StateService {
private _overridingCurrentState$: Subject<AnimationFrame>;

constructor(currentState$: Subject<AnimationFrame>) {
super(State.Traversing);
super(State.Traversing, new S2GeometryProvider());

this._overridingCurrentState$ = currentState$;
}
Expand Down
Loading

0 comments on commit e39ca9c

Please sign in to comment.