Make node properties readonly.

Remove duplicated key param from constructor.
Adjust unit tests.
This commit is contained in:
Oscar Lorentzon 2016-04-20 11:06:35 +02:00
parent 373a84cfa8
commit d90f8d64a9
7 changed files with 211 additions and 162 deletions

View File

@ -15,7 +15,7 @@ describe("Transform.rt", () => {
let r: number[] = [0, 0, 0];
let t: number[] = [0, 0, 0];
let node: Node = new Node("", 0, null, true, null, { key: "", rotation: r }, []);
let node: Node = new Node(0, null, true, null, { key: "", rotation: r }, []);
let transform: Transform = new Transform(node, t);
let Rt: THREE.Matrix4 = transform.rt;
@ -45,7 +45,7 @@ describe("Transform.rt", () => {
let r: number[] = [0, 0, Math.PI];
let t: number[] = [0, 0, 0];
let node: Node = new Node("key", 0, null, true, null, { key: "key", rotation: r }, []);
let node: Node = new Node(0, null, true, null, { key: "key", rotation: r }, []);
let transform: Transform = new Transform(node, t);
let Rt: THREE.Matrix4 = transform.rt;
@ -75,7 +75,7 @@ describe("Transform.rt", () => {
let r: number[] = [Math.PI / 2, 0, 0];
let t: number[] = [0, 0, 0];
let node: Node = new Node("key", 0, null, true, null, { key: "key", rotation: r }, []);
let node: Node = new Node(0, null, true, null, { key: "key", rotation: r }, []);
let transform: Transform = new Transform(node, t);
let Rt: THREE.Matrix4 = transform.rt;
@ -105,7 +105,7 @@ describe("Transform.rt", () => {
let r: number[] = [0, 0, 0];
let t: number[] = [10, 20, 30];
let node: Node = new Node("key", 0, null, true, null, { key: "key", rotation: r }, []);
let node: Node = new Node(0, null, true, null, { key: "key", rotation: r }, []);
let transform: Transform = new Transform(node, t);
let Rt: THREE.Matrix4 = transform.rt;
@ -139,7 +139,7 @@ describe("Transform.srt", () => {
let r: number[] = [0, 0, 0];
let t: number[] = [0, 0, 0];
let node: Node = new Node("", 0, null, true, null, { key: "", rotation: r, atomic_scale: 1 }, []);
let node: Node = new Node(0, null, true, null, { key: "", rotation: r, atomic_scale: 1 }, []);
let transform: Transform = new Transform(node, t);
let sRt: THREE.Matrix4 = transform.srt;
@ -169,7 +169,7 @@ describe("Transform.srt", () => {
let r: number[] = [0, Math.PI / 2, 0];
let t: number[] = [0, 0, 0];
let node: Node = new Node("", 0, null, true, null, { key: "", rotation: r, atomic_scale: 3 }, []);
let node: Node = new Node(0, null, true, null, { key: "", rotation: r, atomic_scale: 3 }, []);
let transform: Transform = new Transform(node, t);
let sRt: THREE.Matrix4 = transform.srt;
@ -199,7 +199,7 @@ describe("Transform.srt", () => {
let r: number[] = [0, 0, 0];
let t: number[] = [-10, 20, -30];
let node: Node = new Node("", 0, null, true, null, { key: "", rotation: r, atomic_scale: 0.5 }, []);
let node: Node = new Node(0, null, true, null, { key: "", rotation: r, atomic_scale: 0.5 }, []);
let transform: Transform = new Transform(node, t);
let sRt: THREE.Matrix4 = transform.srt;
@ -230,7 +230,7 @@ describe("Transform.width", () => {
it("should have fallback width", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -244,7 +244,7 @@ describe("Transform.width", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ width: width, key: "", rotation: [0, 0, 0] },
[]);
@ -258,7 +258,7 @@ describe("Transform.height", () => {
it("should have fallback height", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ height: -1, key: "", rotation: [0, 0, 0] },
[]);
@ -272,7 +272,7 @@ describe("Transform.height", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ height: height, key: "", rotation: [0, 0, 0] },
[]);
@ -286,7 +286,7 @@ describe("Transform.focal", () => {
it("should have fallback focal", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -300,7 +300,7 @@ describe("Transform.focal", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ cfocal: focal, key: "", rotation: [0, 0, 0] },
[]);
@ -314,7 +314,7 @@ describe("Transform.orientation", () => {
it("should have fallback orientation", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -328,7 +328,7 @@ describe("Transform.orientation", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ orientation: orientation, key: "", rotation: [0, 0, 0] },
[]);
@ -342,7 +342,7 @@ describe("Transform.scale", () => {
it("should have fallback scale", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -356,7 +356,7 @@ describe("Transform.scale", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ atomic_scale: scale, key: "", rotation: [0, 0, 0] },
[]);
@ -370,7 +370,7 @@ describe("Transform.gpano", () => {
it("should not have gpano set", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -391,7 +391,7 @@ describe("Transform.gpano", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ gpano: gpano, key: "", rotation: [0, 0, 0] },
[]);
@ -413,7 +413,7 @@ describe("Transform.pixelToVertex", () => {
it("should return vertex at origin", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -429,7 +429,7 @@ describe("Transform.pixelToVertex", () => {
it("should return vertex at inverted translation", () => {
let t: number[] = [10, -20, 30];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -448,7 +448,7 @@ describe("Transform.pixelToVertex", () => {
let t: number[] = geoHelper.getTranslation(r, C);
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: r },
[]);
@ -464,7 +464,7 @@ describe("Transform.pixelToVertex", () => {
it("should return vertex 10 units front of origin in camera direction", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -484,7 +484,7 @@ describe("Transform.pixelToVertex", () => {
let t: number[] = geoHelper.getTranslation(r, C);
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: r },
[]);
@ -505,7 +505,7 @@ describe("Transform.projectBasic", () => {
it("should project to the image center", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -520,7 +520,7 @@ describe("Transform.projectBasic", () => {
it("should project to the first quadrant", () => {
let t: number[] = [0, 0, 0];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0, 0, 0] },
[]);
@ -539,7 +539,7 @@ describe("Transform.unprojectBasic", () => {
it("should back-project to the same pixel", () => {
let t: number[] = [10, 20, 30];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{ key: "", rotation: [0.1, 0.2, 0.3] },
[]);
@ -558,7 +558,7 @@ describe("Transform.unprojectBasic", () => {
it("should back-project to the same pixel for full pano", () => {
let t: number[] = [5, 15, 2];
let node: Node = new Node(
"", 0, null, true, null,
0, null, true, null,
{
gpano: {
CroppedAreaLeftPixels: 0,

View File

@ -1,13 +1,13 @@
/// <reference path="../../typings/browser.d.ts" />
import {IAPINavImIm} from "../../src/API";
import {IAPINavImIm, IAPINavImS} from "../../src/API";
import {Node, Sequence} from "../../src/Graph";
describe("Node", () => {
var sequence: Sequence;
beforeEach(() => {
let response: any = {
let response: IAPINavImS = {
key: 'A',
keys: ['B','C','D','E'],
path: {}
@ -16,53 +16,53 @@ describe("Node", () => {
});
it("should create a node", () => {
let node: Node = new Node("C", 0, {lat: 1, lon: 1}, true, sequence, null, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "C" }, null);
expect(node).toBeDefined();
});
it("should find next node key in nodes sequence", () => {
let node: Node = new Node("C", 0, {lat: 1, lon: 1}, true, sequence, null, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "C" }, null);
expect(node.findNextKeyInSequence()).toEqual('D')
});
it("should find prev node key in nodes sequence", () => {
let node: Node = new Node("C", 0, {lat: 1, lon: 1}, true, sequence, null, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "C" }, null);
expect(node.findPrevKeyInSequence()).toEqual('B')
});
it("should return null if no next key", () => {
let node: Node = new Node("E", 0, {lat: 1, lon: 1}, true, sequence, null, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "E" }, null);
expect(node.findNextKeyInSequence()).toBe(null)
});
it("should return null if no prev key", () => {
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, null, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "B" }, null);
expect(node.findPrevKeyInSequence()).toBe(null)
});
it("should not be merged", () => {
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, null, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "B" }, null);
expect(node.merged).toBe(false)
});
it("should not be merged because merge version is zero", () => {
let apiNavImIm: IAPINavImIm = { key: "B", merge_version: 0}
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
expect(node.merged).toBe(false)
});
it("should be merged because merge version present and larger than zero", () => {
let apiNavImIm: IAPINavImIm = { key: "B", merge_version: 4}
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
expect(node.merged).toBe(true)
});
it("should not be full pano when gpano is null", () => {
let apiNavImIm: IAPINavImIm = { key: "B", gpano: null }
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
expect(node.fullPano).toBe(false)
});
@ -79,7 +79,7 @@ describe("Node", () => {
}
};
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
expect(node.fullPano).toBe(false)
});
@ -96,7 +96,7 @@ describe("Node", () => {
}
};
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
expect(node.fullPano).toBe(false)
});
@ -113,7 +113,7 @@ describe("Node", () => {
}
};
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
expect(node.fullPano).toBe(false)
});
@ -130,7 +130,7 @@ describe("Node", () => {
}
};
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
expect(node.fullPano).toBe(false)
});
@ -147,7 +147,7 @@ describe("Node", () => {
}
};
let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null);
expect(node.fullPano).toBe(true)
});
});

View File

@ -21,7 +21,7 @@ describe("EdgeCalculator.computeSequenceEdges", () => {
let apiNavImIm: IAPINavImIm = { key: key };
let node: Node = new Node(key, 0, {lat: 0, lon: 0}, true, sequence, apiNavImIm, []);
let node: Node = new Node(0, {lat: 0, lon: 0}, true, sequence, apiNavImIm, []);
return node;
}

View File

@ -57,7 +57,7 @@ describe("EdgeCalculator.getPotentialEdges", () => {
} :
apiNavImIm;
return new Node(key, 0, latLonAlt, true, sequence, apiNavImIm, []);
return new Node(0, latLonAlt, true, sequence, apiNavImIm, []);
};
let createRotationVector = (azimuth: number, norm: number = Math.PI / 2): number[] => {
@ -80,7 +80,7 @@ describe("EdgeCalculator.getPotentialEdges", () => {
});
it("should return empty array when node is not worthy", () => {
let node: Node = new Node("key", 0, null, false, null, null, null);
let node: Node = new Node(0, null, false, null, { key: "" }, null);
let result: IPotentialEdge[] =
edgeCalculator.getPotentialEdges(node, null, []);

View File

@ -38,7 +38,7 @@ export class EdgeCalculatorHelper {
}
}
let node: Node = new Node(key, 0, {lat: 0, lon: 0}, true, sequence, apiNavImIm, []);
let node: Node = new Node(0, {lat: 0, lon: 0}, true, sequence, apiNavImIm, []);
return node;
}

View File

@ -135,18 +135,7 @@ export class Graph {
}
}
let node: Node = new Node(
im.key,
ca,
latLon,
false,
sequence,
im,
hs
);
node.user = im.user;
node.capturedAt = im.captured_at;
let node: Node = new Node(ca, latLon, false, sequence, im, hs);
this._unWorthyNodes[im.key] = true;

View File

@ -14,143 +14,109 @@ interface ILoadStatusObject {
}
export class Node {
public key: string;
public user: string;
public capturedAt: number;
public ca: number;
public latLon: ILatLon;
public worthy: boolean;
public sequence: Sequence;
public apiNavImIm: IAPINavImIm;
public cached: boolean;
public lastCacheEvict: number;
public lastUsed: number;
public image: any;
public mesh: IMesh;
public edges: IEdge[];
private _apiNavImIm: IAPINavImIm;
private _key: string;
private _ca: number;
private _latLon: ILatLon;
private _sequence: Sequence;
public hs: string[];
private _hs: string[];
public loadStatus: ILoadStatus;
private _image: HTMLImageElement;
private _mesh: IMesh;
private _edges: IEdge[];
private _loadStatus: ILoadStatus;
constructor (
key: string,
ca: number,
latLon: ILatLon,
worthy: boolean,
sequence: Sequence,
apiNavImIm: IAPINavImIm,
hs: string[]) {
this.key = key;
this.ca = ca;
this.latLon = latLon;
this._apiNavImIm = apiNavImIm;
this._key = apiNavImIm.key;
this._ca = ca;
this._latLon = latLon;
this._sequence = sequence;
this._hs = hs;
this._image = null;
this._mesh = null;
this._edges = null;
this.worthy = worthy;
this.sequence = sequence;
this.apiNavImIm = apiNavImIm;
this.cached = false;
this.lastCacheEvict = 0;
this.lastUsed = new Date().getTime();
this.hs = hs;
this.loadStatus = {loaded: 0, total: 100};
this._loadStatus = { loaded: 0, total: 100 };
}
public cacheAssets(): rx.Observable<Node> {
return this.cacheImage().combineLatest(this.cacheMesh(), (image: ILoadStatusObject, mesh: ILoadStatusObject): Node => {
this.loadStatus.loaded = 0;
this.loadStatus.total = 0;
if (mesh) {
this.mesh = mesh.object;
this.loadStatus.loaded += mesh.loaded.loaded;
this.loadStatus.total += mesh.loaded.total;
}
if (image) {
this.image = image.object;
this.loadStatus.loaded += image.loaded.loaded;
this.loadStatus.total += image.loaded.total;
}
return this;
});
public get apiNavImIm(): IAPINavImIm {
return this._apiNavImIm;
}
public cacheImage(): rx.Observable<ILoadStatusObject> {
return rx.Observable.create<ILoadStatusObject>((observer: rx.Observer<ILoadStatusObject>): void => {
let img: HTMLImageElement = new Image();
img.crossOrigin = "Anonymous";
if (process.env.MAPENV === "development") {
observer.onNext({loaded: {loaded: 1, total: 1}, object: this.image});
observer.onCompleted();
return;
}
let xmlHTTP: XMLHttpRequest = new XMLHttpRequest();
xmlHTTP.open("GET", Urls.image(this.key, Settings.baseImageSize), true);
xmlHTTP.responseType = "arraybuffer";
xmlHTTP.onload = (e: any) => {
img.onload = () => {
observer.onNext({loaded: {loaded: e.loaded, total: e.total}, object: img});
observer.onCompleted();
};
img.onerror = (err: Event) => {
observer.onError(err);
};
let blob: Blob = new Blob([xmlHTTP.response]);
img.src = window.URL.createObjectURL(blob);
};
xmlHTTP.onprogress = (e: any) => {
observer.onNext({loaded: {loaded: e.loaded, total: e.total}, object: null});
};
xmlHTTP.send();
});
public get user(): string {
return this._apiNavImIm.user;
}
public cacheMesh(): rx.Observable<ILoadStatusObject> {
return rx.Observable.create<ILoadStatusObject>((observer: rx.Observer<ILoadStatusObject>): void => {
if (process.env.MAPENV === "development") {
observer.onNext({loaded: {loaded: 1, total: 1}, object: { faces: [[-1]], vertices: [[-1]] }});
observer.onCompleted();
return;
}
public get capturedAt(): number {
return this._apiNavImIm.captured_at;
}
if (!this.merged) {
let mesh: IMesh = { faces: [], vertices: [] };
observer.onNext({ loaded: { loaded: 0, total: 0 }, object: mesh });
observer.onCompleted();
public get key(): string {
return this._key;
}
return;
}
public get ca(): number {
return this._ca;
}
let xmlHTTP: XMLHttpRequest = new XMLHttpRequest();
xmlHTTP.open("GET", Urls.proto_mesh(this.key), true);
xmlHTTP.responseType = "arraybuffer";
xmlHTTP.onload = (e: any) => {
let mesh: IMesh;
if (xmlHTTP.status === 200) {
mesh = MeshReader.read(new Buffer(xmlHTTP.response));
} else {
mesh = { faces: [], vertices: [] };
}
public get latLon(): ILatLon {
return this._latLon;
}
observer.onNext({ loaded: {loaded: e.loaded, total: e.total }, object: mesh });
observer.onCompleted();
};
public get sequence(): Sequence {
return this._sequence;
}
xmlHTTP.onprogress = (e: any) => {
observer.onNext({ loaded: { loaded: e.loaded, total: e.total }, object: null});
};
public get hs(): string[] {
return this._hs;
}
xmlHTTP.send(null);
});
public get image(): HTMLImageElement {
return this._image;
}
public get mesh(): IMesh {
return this._mesh;
}
public get edges(): IEdge[] {
return this._edges;
}
public set edges(value: IEdge[]) {
this._edges = value;
}
public get loadStatus(): ILoadStatus {
return this._loadStatus;
}
public get loaded(): boolean {
return this.cached && this.image != null;
return this.cached && this._image != null;
}
public get merged(): boolean {
@ -185,6 +151,100 @@ export class Node {
}
return this.sequence.findPrevKey(this.key);
}
public cacheAssets(): rx.Observable<Node> {
return this.cacheImage().combineLatest(this.cacheMesh(), (image: ILoadStatusObject, mesh: ILoadStatusObject): Node => {
this._loadStatus.loaded = 0;
this._loadStatus.total = 0;
if (mesh) {
this._mesh = mesh.object;
this._loadStatus.loaded += mesh.loaded.loaded;
this._loadStatus.total += mesh.loaded.total;
}
if (image) {
this._image = image.object;
this._loadStatus.loaded += image.loaded.loaded;
this._loadStatus.total += image.loaded.total;
}
return this;
});
}
public cacheImage(): rx.Observable<ILoadStatusObject> {
return rx.Observable.create<ILoadStatusObject>((observer: rx.Observer<ILoadStatusObject>): void => {
let img: HTMLImageElement = new Image();
img.crossOrigin = "Anonymous";
if (process.env.MAPENV === "development") {
observer.onNext({ loaded: {loaded: 1, total: 1}, object: this._image });
observer.onCompleted();
return;
}
let xmlHTTP: XMLHttpRequest = new XMLHttpRequest();
xmlHTTP.open("GET", Urls.image(this.key, Settings.baseImageSize), true);
xmlHTTP.responseType = "arraybuffer";
xmlHTTP.onload = (e: any) => {
img.onload = () => {
observer.onNext({ loaded: { loaded: e.loaded, total: e.total }, object: img });
observer.onCompleted();
};
img.onerror = (err: Event) => {
observer.onError(err);
};
let blob: Blob = new Blob([xmlHTTP.response]);
img.src = window.URL.createObjectURL(blob);
};
xmlHTTP.onprogress = (e: any) => {
observer.onNext({loaded: { loaded: e.loaded, total: e.total}, object: null });
};
xmlHTTP.send();
});
}
public cacheMesh(): rx.Observable<ILoadStatusObject> {
return rx.Observable.create<ILoadStatusObject>((observer: rx.Observer<ILoadStatusObject>): void => {
if (process.env.MAPENV === "development") {
observer.onNext({loaded: { loaded: 1, total: 1}, object: { faces: [[-1]], vertices: [[-1]] } });
observer.onCompleted();
return;
}
if (!this.merged) {
let mesh: IMesh = { faces: [], vertices: [] };
observer.onNext({ loaded: { loaded: 0, total: 0 }, object: mesh });
observer.onCompleted();
return;
}
let xmlHTTP: XMLHttpRequest = new XMLHttpRequest();
xmlHTTP.open("GET", Urls.proto_mesh(this.key), true);
xmlHTTP.responseType = "arraybuffer";
xmlHTTP.onload = (e: any) => {
let mesh: IMesh;
if (xmlHTTP.status === 200) {
mesh = MeshReader.read(new Buffer(xmlHTTP.response));
} else {
mesh = { faces: [], vertices: [] };
}
observer.onNext({ loaded: { loaded: e.loaded, total: e.total }, object: mesh });
observer.onCompleted();
};
xmlHTTP.onprogress = (e: any) => {
observer.onNext({ loaded: { loaded: e.loaded, total: e.total }, object: null });
};
xmlHTTP.send(null);
});
}
}
export default Node;