Skip to content

Commit a1ed2e1

Browse files
Intersect only interactive objects.
Improve performance by not intersecting parents and siblings of interactive objects. Keep array of interactive objects in marker scene.
1 parent 5121db6 commit a1ed2e1

7 files changed

Lines changed: 39 additions & 28 deletions

File tree

spec/component/marker/Marker.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class TestMarker extends Marker {
1515
}
1616

1717
protected _disposeGeometry(): void { /* noop */ }
18-
protected _getInteractiveObjectIds(): string[] { return [this._geometry.uuid]; }
18+
protected _getInteractiveObjects(): THREE.Object3D[] { return [this._geometry]; }
1919
}
2020

2121
describe("Marker.ctor", () => {
@@ -62,18 +62,18 @@ describe("Marker.disposeGeometry", () => {
6262
describe("Marker.getInteractiveObjectIds", () => {
6363
it("should return empty array if geometry not defined", () => {
6464
let marker: Marker = new TestMarker("id", { lat: 1, lon: 2 });
65-
let objectIds: string[] = marker.getInteractiveObjectIds();
65+
let objects: THREE.Object3D[] = marker.getInteractiveObjects();
6666

67-
expect(objectIds.length).toBe(0);
67+
expect(objects.length).toBe(0);
6868
});
6969

7070
it("should return object ids when geometry created", () => {
7171
let marker: Marker = new TestMarker("id", { lat: 1, lon: 2 });
7272
marker.createGeometry([0, 0, 0]);
73-
let objectIds: string[] = marker.getInteractiveObjectIds();
73+
let objects: THREE.Object3D[] = marker.getInteractiveObjects();
7474

75-
expect(objectIds.length).toBe(1);
76-
expect(objectIds[0]).toBe(marker.geometry.uuid);
75+
expect(objects.length).toBe(1);
76+
expect(objects[0].uuid).toBe(marker.geometry.uuid);
7777
});
7878
});
7979

spec/component/marker/MarkerScene.spec.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class TestMarker extends Marker {
1212
constructor(id: string, latLon: ILatLon) { super(id, latLon); }
1313
protected _createGeometry(position: number[]): void { /* noop */ }
1414
protected _disposeGeometry(): void { /* noop */ }
15-
protected _getInteractiveObjectIds(): string[] { return []; }
15+
protected _getInteractiveObjects(): THREE.Object3D[] { return []; }
1616
}
1717

1818
class RendererMock implements THREE.Renderer {
@@ -50,16 +50,16 @@ describe("MarkerScene.add", () => {
5050
let marker: TestMarker = new TestMarker("id", { lat: 0, lon: 0 });
5151

5252
let createGeometrySpy: jasmine.Spy = spyOn(marker, "createGeometry").and.stub();
53-
let getInteractiveIdsSpy: jasmine.Spy = spyOn(marker, "getInteractiveObjectIds");
54-
getInteractiveIdsSpy.and.returnValue([]);
53+
let getInteractiveSpy: jasmine.Spy = spyOn(marker, "getInteractiveObjects");
54+
getInteractiveSpy.and.returnValue([]);
5555

5656
markerScene.add(marker, [0, 0, 0]);
5757

5858
expect(markerScene.get(marker.id)).toBe(marker);
5959

6060
expect(sceneAddSpy.calls.count()).toBe(1);
6161
expect(createGeometrySpy.calls.count()).toBe(1);
62-
expect(getInteractiveIdsSpy.calls.count()).toBe(1);
62+
expect(getInteractiveSpy.calls.count()).toBe(1);
6363

6464
expect(markerScene.needsRender).toBe(true);
6565
});
@@ -75,7 +75,7 @@ describe("MarkerScene.render", () => {
7575
let marker: TestMarker = new TestMarker("id", { lat: 0, lon: 0 });
7676

7777
spyOn(marker, "createGeometry").and.stub();
78-
spyOn(marker, "getInteractiveObjectIds").and.returnValue([]);
78+
spyOn(marker, "getInteractiveObjects").and.returnValue([]);
7979

8080
markerScene.add(marker, [0, 0, 0]);
8181

@@ -101,7 +101,7 @@ describe("MarkerScene.clear", () => {
101101
let marker: TestMarker = new TestMarker("id", { lat: 0, lon: 0 });
102102

103103
spyOn(marker, "createGeometry").and.stub();
104-
spyOn(marker, "getInteractiveObjectIds").and.returnValue([]);
104+
spyOn(marker, "getInteractiveObjects").and.returnValue([]);
105105

106106
let disposeGeometrySpy: jasmine.Spy = spyOn(marker, "disposeGeometry");
107107

@@ -131,7 +131,7 @@ describe("MarkerScene.remove", () => {
131131
let marker: TestMarker = new TestMarker("id", { lat: 0, lon: 0 });
132132

133133
spyOn(marker, "createGeometry").and.stub();
134-
spyOn(marker, "getInteractiveObjectIds").and.returnValue([]);
134+
spyOn(marker, "getInteractiveObjects").and.returnValue([]);
135135

136136
let disposeGeometrySpy: jasmine.Spy = spyOn(marker, "disposeGeometry");
137137

@@ -162,7 +162,7 @@ describe("MarkerScene.has", () => {
162162
let marker: TestMarker = new TestMarker("id", { lat: 0, lon: 0 });
163163

164164
spyOn(marker, "createGeometry").and.stub();
165-
spyOn(marker, "getInteractiveObjectIds").and.returnValue([]);
165+
spyOn(marker, "getInteractiveObjects").and.returnValue([]);
166166
spyOn(marker, "disposeGeometry");
167167

168168
markerScene.add(marker, [0, 0, 0]);
@@ -185,7 +185,7 @@ describe("MarkerScene.update", () => {
185185
let marker: TestMarker = new TestMarker("id", { lat: 0, lon: 0 });
186186

187187
spyOn(marker, "createGeometry").and.stub();
188-
spyOn(marker, "getInteractiveObjectIds").and.returnValue([]);
188+
spyOn(marker, "getInteractiveObjects").and.returnValue([]);
189189
let updateSpy: jasmine.Spy = spyOn(marker, "updatePosition");
190190

191191
markerScene.add(marker, [0, 0, 0]);
@@ -201,6 +201,7 @@ describe("MarkerScene.intersectObjects", () => {
201201
spyOn(scene, "add").and.stub();
202202

203203
let interactiveObjectId: string = "interactive-id";
204+
let interactiveObject: THREE.Object3D = <THREE.Object3D>{ uuid: interactiveObjectId };
204205
let intersection: THREE.Intersection =
205206
<THREE.Intersection>{ object: { uuid: interactiveObjectId }};
206207

@@ -210,7 +211,7 @@ describe("MarkerScene.intersectObjects", () => {
210211

211212
let marker: TestMarker = new TestMarker("id", { lat: 0, lon: 0 });
212213
spyOn(marker, "createGeometry").and.stub();
213-
spyOn(marker, "getInteractiveObjectIds").and.returnValue([interactiveObjectId]);
214+
spyOn(marker, "getInteractiveObjects").and.returnValue([interactiveObject]);
214215

215216
let markerScene: MarkerScene = new MarkerScene(scene, raycaster);
216217
markerScene.add(marker, [0, 0, 0]);

spec/component/marker/MarkerSet.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class TestMarker extends Marker {
1212
constructor(id: string, latLon: ILatLon) { super(id, latLon); }
1313
protected _createGeometry(position: number[]): void { /* noop */ }
1414
protected _disposeGeometry(): void { /* noop */ }
15-
protected _getInteractiveObjectIds(): string[] { return []; }
15+
protected _getInteractiveObjects(): THREE.Object3D[] { return []; }
1616
}
1717

1818
describe("MarkerSet.ctor", () => {

src/component/marker/MarkerScene.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import {Marker} from "../../Component";
77

88
export class MarkerScene {
99
private _needsRender: boolean;
10+
private _interactiveObjects: THREE.Object3D[];
1011
private _markers: { [key: string]: Marker };
1112
private _objectMarkers: { [id: string]: string };
1213
private _raycaster: THREE.Raycaster;
1314
private _scene: THREE.Scene;
1415

1516
constructor(scene?: THREE.Scene, raycaster?: THREE.Raycaster) {
1617
this._needsRender = false;
18+
this._interactiveObjects = [];
1719
this._markers = {};
1820
this._objectMarkers = {};
1921
this._raycaster = !!raycaster ? raycaster : new THREE.Raycaster();
@@ -36,8 +38,9 @@ export class MarkerScene {
3638
marker.createGeometry(position);
3739
this._scene.add(marker.geometry);
3840
this._markers[marker.id] = marker;
39-
for (let interactiveId of marker.getInteractiveObjectIds()) {
40-
this._objectMarkers[interactiveId] = marker.id;
41+
for (let interactiveObject of marker.getInteractiveObjects()) {
42+
this._interactiveObjects.push(interactiveObject);
43+
this._objectMarkers[interactiveObject.uuid] = marker.id;
4144
}
4245

4346
this._needsRender = true;
@@ -72,7 +75,7 @@ export class MarkerScene {
7275
public intersectObjects([viewportX, viewportY]: number[], camera: THREE.Camera): string {
7376
this._raycaster.setFromCamera(new THREE.Vector2(viewportX, viewportY), camera);
7477

75-
const intersects: THREE.Intersection[] = this._raycaster.intersectObjects(this._scene.children, true);
78+
const intersects: THREE.Intersection[] = this._raycaster.intersectObjects(this._interactiveObjects);
7679
for (const intersect of intersects) {
7780
if (intersect.object.uuid in this._objectMarkers) {
7881
return this._objectMarkers[intersect.object.uuid];
@@ -125,8 +128,15 @@ export class MarkerScene {
125128
private _dispose(id: string): void {
126129
const marker: Marker = this._markers[id];
127130
this._scene.remove(marker.geometry);
128-
for (let interactiveId of marker.getInteractiveObjectIds()) {
129-
delete this._objectMarkers[interactiveId];
131+
for (let interactiveObject of marker.getInteractiveObjects()) {
132+
const index: number = this._interactiveObjects.indexOf(interactiveObject);
133+
if (index !== -1) {
134+
this._interactiveObjects.splice(index, 1);
135+
} else {
136+
console.warn(`Object does not exist (${interactiveObject.id}) for ${id}`);
137+
}
138+
139+
delete this._objectMarkers[interactiveObject.uuid];
130140
}
131141

132142
marker.disposeGeometry();

src/component/marker/marker/CircleMarker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class CircleMarker extends Marker {
7777
}
7878
}
7979

80-
protected _getInteractiveObjectIds(): string[] {
80+
protected _getInteractiveObjects(): THREE.Object3D[] {
8181
return [];
8282
}
8383
}

src/component/marker/marker/Marker.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ export abstract class Marker {
6161
this._geometry = undefined;
6262
}
6363

64-
public getInteractiveObjectIds(): string[] {
64+
public getInteractiveObjects(): THREE.Object3D[] {
6565
if (!this._geometry) {
6666
return [];
6767
}
6868

69-
return this._getInteractiveObjectIds();
69+
return this._getInteractiveObjects();
7070
}
7171

7272
public lerpAltitude(alt: number, alpha: number): void {
@@ -95,7 +95,7 @@ export abstract class Marker {
9595

9696
protected abstract _disposeGeometry(): void;
9797

98-
protected abstract _getInteractiveObjectIds(): string[];
98+
protected abstract _getInteractiveObjects(): THREE.Object3D[];
9999
}
100100

101101
export default Marker;

src/component/marker/marker/SimpleMarker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ export class SimpleMarker extends Marker {
101101
}
102102
}
103103

104-
protected _getInteractiveObjectIds(): string[] {
105-
return this._interactive ? [this._geometry.children[0].uuid] : [];
104+
protected _getInteractiveObjects(): THREE.Object3D[] {
105+
return this._interactive ? [this._geometry.children[0]] : [];
106106
}
107107

108108
private _markerHeight(radius: number): number {

0 commit comments

Comments
 (0)