import vtkActor from ‘vtk.js/Sources/Rendering/Core/Actor’;
import vtkMapper from ‘vtk.js/Sources/Rendering/Core/Mapper’;
import vtkOpenGLRenderWindow from ‘vtk.js/Sources/Rendering/OpenGL/RenderWindow’;
import vtkRenderWindow from ‘vtk.js/Sources/Rendering/Core/RenderWindow’;
import vtkCamera from ‘vtk.js/Sources/Rendering/Core/Camera’;
import vtkRenderWindowInteractor from ‘vtk.js/Sources/Rendering/Core/RenderWindowInteractor’;
import vtkRenderer from ‘vtk.js/Sources/Rendering/Core/Renderer’;
//import vtkInteractorStyleTrackballCamera from ‘vtk.js/Sources/Interaction/Style/InteractorStyleTrackballCamera’;
import vtkInteractorStyleTrackballCamera from ‘vtk.js/Sources/Interaction/Style/InteractorStyleRadarCamera’;
//import vtkInteractorStyleRadarCamera from ‘vtk.js/Sources/Interaction/Style/InteractorStyleRadarCamera’;
import vtkMath from ‘vtk.js/Sources/Common/Core/Math’;
import vtkTexture from ‘vtk.js/Sources/Rendering/Core/Texture’;
import vtkXMLPolyDataReader from ‘vtk.js/Sources/IO/XML/XMLPolyDataReader’;
import { vec3, quat, mat3, mat4 } from ‘gl-matrix’;
import RadialImgRadarProduct = require(‘./radar_img_radial_product’)
import RadialRpgRadarProduct = require(‘./radar_rpg_radial_product’)
class RadarRenderWindow {
private radialRadarProduct1;
private radialRadarProduct2;
private siteLat: number;
private siteLon: number;
private loopIndex: number = 0;
private renderWindow = vtkRenderWindow.newInstance();
private openGlRenderWindow = vtkOpenGLRenderWindow.newInstance();
private renCam = vtkCamera.newInstance();
private globeRenderer1 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private radarRenderer1 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private mapRenderer1 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private globeRenderer2 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private radarRenderer2 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private mapRenderer2 = vtkRenderer.newInstance({ background: [0, 0, 0] });
/*private globeRenderer3 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private radarRenderer3 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private mapRenderer3 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private globeRenderer4 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private radarRenderer4 = vtkRenderer.newInstance({ background: [0, 0, 0] });
private mapRenderer4 = vtkRenderer.newInstance({ background: [0, 0, 0] });*/
private globeActor = vtkActor.newInstance();
private globeMapper = vtkMapper.newInstance();
private mapActor = vtkActor.newInstance();
private mapMapper = vtkMapper.newInstance();
private interactor = vtkRenderWindowInteractor.newInstance();
private numRadarLoopProds = 12;
public radarLoopLoadedCallback: () => void;
public radarLoadingProgressCallback: (ev: ProgressEvent<EventTarget>, index: number) => void;
public radarLoadingStartCallback: (index: number) => void;
public radarLoadingEndCallback: () => void;
public constructor(numlayers: number, numprods: number, rproctype: number) {
this.numRadarLoopProds = numprods;
this.renderWindow.addView(this.openGlRenderWindow);
this.renderWindow.setNumberOfLayers(numlayers);
this.renCam.setClippingRange(10000.0, 10000000.0);
this.globeRenderer1.setLayer(0);
this.globeRenderer1.setActiveCamera(this.renCam);
//this.globeRenderer1.setViewport(0.001, 0.51, 0.495, 0.99);
this.globeRenderer1.setViewport(0.001, 0.01, 0.495, 0.99);
this.globeRenderer2.setLayer(0);
this.globeRenderer2.setActiveCamera(this.renCam);
//this.globeRenderer2.setViewport(0.501, 0.51, 0.995, 0.99);
this.globeRenderer2.setViewport(0.501, 0.01, 0.995, 0.99);
/*this.globeRenderer3.setLayer(0);
this.globeRenderer3.setActiveCamera(this.renCam);
this.globeRenderer3.setViewport(0.001, 0.01, 0.495, 0.49);
this.globeRenderer4.setLayer(0);
this.globeRenderer4.setActiveCamera(this.renCam);
this.globeRenderer4.setViewport(0.501, 0.01, 0.995, 0.49);*/
this.radarRenderer1.setLayer(1);
this.radarRenderer1.setActiveCamera(this.renCam);
this.radarRenderer1.setPreserveDepthBuffer(true);
//this.radarRenderer1.setViewport(0.001, 0.51, 0.495, 0.99);
this.radarRenderer1.setViewport(0.001, 0.01, 0.495, 0.99);
this.radarRenderer2.setLayer(1);
this.radarRenderer2.setActiveCamera(this.renCam);
this.radarRenderer2.setPreserveDepthBuffer(true);
//this.radarRenderer2.setViewport(0.501, 0.51, 0.995, 0.99);
this.radarRenderer2.setViewport(0.501, 0.01, 0.995, 0.99);
/*this.radarRenderer3.setLayer(1);
this.radarRenderer3.setActiveCamera(this.renCam);
this.radarRenderer3.setPreserveDepthBuffer(true);
this.radarRenderer3.setViewport(0.001, 0.01, 0.495, 0.49);
this.radarRenderer4.setLayer(1);
this.radarRenderer4.setActiveCamera(this.renCam);
this.radarRenderer4.setPreserveDepthBuffer(true);
this.radarRenderer4.setViewport(0.501, 0.01, 0.995, 0.49);*/
this.mapRenderer1.setLayer(2);
this.mapRenderer1.setActiveCamera(this.renCam);
//this.mapRenderer1.setViewport(0.001, 0.51, 0.495, 0.99);
this.mapRenderer1.setViewport(0.001, 0.01, 0.495, 0.99);
this.mapRenderer2.setLayer(2);
this.mapRenderer2.setActiveCamera(this.renCam);
//this.mapRenderer2.setViewport(0.501, 0.51, 0.995, 0.99);
this.mapRenderer2.setViewport(0.501, 0.01, 0.995, 0.99);
/*this.mapRenderer3.setLayer(2);
this.mapRenderer3.setActiveCamera(this.renCam);
this.mapRenderer3.setViewport(0.001, 0.01, 0.495, 0.49);
this.mapRenderer4.setLayer(2);
this.mapRenderer4.setActiveCamera(this.renCam);
this.mapRenderer4.setViewport(0.501, 0.01, 0.995, 0.49);*/
this.renderWindow.addRenderer(this.globeRenderer1);
this.renderWindow.addRenderer(this.globeRenderer2);
/*this.renderWindow.addRenderer(this.globeRenderer3);
this.renderWindow.addRenderer(this.globeRenderer4);*/
this.renderWindow.addRenderer(this.radarRenderer1);
this.renderWindow.addRenderer(this.radarRenderer2);
/*this.renderWindow.addRenderer(this.radarRenderer3);
this.renderWindow.addRenderer(this.radarRenderer4);*/
this.renderWindow.addRenderer(this.mapRenderer1);
this.renderWindow.addRenderer(this.mapRenderer2);
/*this.renderWindow.addRenderer(this.mapRenderer3);
this.renderWindow.addRenderer(this.mapRenderer4);*/
if (rproctype === 2) {
this.radialRadarProduct1 = new RadialRpgRadarProduct(numprods, this.radarRenderer1);
this.radialRadarProduct2 = new RadialRpgRadarProduct(numprods, this.radarRenderer2);
} else {
this.radialRadarProduct1 = new RadialImgRadarProduct(numprods, this.radarRenderer1);
this.radialRadarProduct2 = new RadialImgRadarProduct(numprods, this.radarRenderer2);
}
}
public setSize(width: number, height: number): void {
this.openGlRenderWindow.setSize(width, height);
}
public initializeInteractor(rootContainer: HTMLElement): void {
this.openGlRenderWindow.setContainer(rootContainer);
this.interactor.setView(this.openGlRenderWindow);
this.interactor.initialize();
this.interactor.bindEvents(rootContainer);
this.interactor.setInteractorStyle(vtkInteractorStyleTrackballCamera.newInstance());
}
public setRadarColorTable1(colors: Uint8Array): void {
this.radialRadarProduct1.setRadarColorTable(colors);
}
public setRadarColorTable2(colors: Uint8Array): void {
this.radialRadarProduct2.setRadarColorTable(colors);
}
public connectGlobePolydata(fileContents: any): void {
const vtpReader = vtkXMLPolyDataReader.newInstance();
vtpReader.parseAsArrayBuffer(fileContents);
this.globeMapper.setInputConnection(vtpReader.getOutputPort());
}
public connectGlobeTexture(imageElement: HTMLImageElement): void {
const globeTexture = vtkTexture.newInstance();
globeTexture.setRepeat(true);
globeTexture.setImage(imageElement);
this.globeActor.addTexture(globeTexture);
this.globeActor.setMapper(this.globeMapper);
this.globeActor.getProperty().setLighting(false);
this.globeRenderer1.addActor(this.globeActor);
this.globeRenderer2.addActor(this.globeActor);
/*this.globeRenderer3.addActor(this.globeActor);
this.globeRenderer4.addActor(this.globeActor);*/
}
public setInitialCameraConfiguration(): void {
let erm = 6356750.0;
let radwp = this.computeGlobePoint(this.siteLon, this.siteLat, erm);
this.renCam.setViewUp(radwp[0], radwp[1], radwp[2]);
let positionVector = vec3.create();
positionVector[0] = radwp[0];
positionVector[1] = radwp[1];
positionVector[2] = radwp[2];
vtkMath.multiplyScalar(positionVector, 1.15);
this.setCameraPosition(positionVector[0], positionVector[1], positionVector[2] - 1000.0);
this.setCameraFocalPoint(radwp[0], radwp[1], radwp[2]);
this.render();
}
public connectCountyLinePolydata(fileContents: any): void {
const vtpCountyLineReader = vtkXMLPolyDataReader.newInstance();
vtpCountyLineReader.parseAsArrayBuffer(fileContents);
this.mapMapper.setInputConnection(vtpCountyLineReader.getOutputPort());
this.mapActor.setMapper(this.mapMapper);
this.mapActor.getProperty().setLighting(false);
this.mapRenderer1.addActor(this.mapActor);
this.mapRenderer2.addActor(this.mapActor);
/*this.mapRenderer3.addActor(this.mapActor);
this.mapRenderer4.addActor(this.mapActor);*/
}
public setCameraPosition(posx: number, posy: number, posz: number): void {
this.renCam.setPosition(posx, posy, posz);
this.renCam.elevation(-1);
}
public setCameraFocalPoint(posx: number, posy: number, posz: number): void {
this.renCam.setFocalPoint(posx, posy, posz);
}
private render(): void {
this.renderWindow.render();
}
loadIntitialRadarLoop1(rpgProducts: any): void {
this.siteLat = rpgProducts[0].LatitudeOfRadar / 1000.0;
this.siteLon = rpgProducts[0].LongitudeOfRadar / 1000.0;
this.setInitialCameraConfiguration();
let base = this;
this.radialRadarProduct1.productLoopLoadedCallback = function () {
base.render();
base.radarLoopLoadedCallback();
}
this.radialRadarProduct1.productLoadingStartCallback = function (index) {
base.radarLoadingStartCallback(index);
}
this.radialRadarProduct1.productLoadingProgressCallback = function (ev, index) {
base.radarLoadingProgressCallback(ev, index);
}
this.radialRadarProduct1.productLoadingEndCallback = function () {
base.render();
base.radarLoadingEndCallback();
}
this.radialRadarProduct1.loadIntitialRadarLoop(rpgProducts);
}
loadIntitialRadarLoop2(rpgProducts: any, view: number): void {
let base = this;
this.radialRadarProduct2.productLoopLoadedCallback = function () {
base.render();
//base.radarLoopLoadedCallback();
}
this.radialRadarProduct2.productLoadingStartCallback = function (index) {
//base.radarLoadingStartCallback(index);
}
this.radialRadarProduct2.productLoadingProgressCallback = function (ev, index) {
//base.radarLoadingProgressCallback(ev, index);
}
this.radialRadarProduct2.productLoadingEndCallback = function () {
base.render();
//base.radarLoadingEndCallback();
}
this.radialRadarProduct2.loadIntitialRadarLoop(rpgProducts);
}
public base64Encode(inputStr): string {
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var outputStr = "";
var i = 0;
while (i < inputStr.length) {
//all three "& 0xff" added below are there to fix a known bug
//with bytes returned by xhr.responseText
var byte1 = inputStr.charCodeAt(i++) & 0xff;
var byte2 = inputStr.charCodeAt(i++) & 0xff;
var byte3 = inputStr.charCodeAt(i++) & 0xff;
var enc1 = byte1 >> 2;
var enc2 = ((byte1 & 3) << 4) | (byte2 >> 4);
var enc3, enc4;
if (isNaN(byte2)) {
enc3 = enc4 = 64;
}
else {
enc3 = ((byte2 & 15) << 2) | (byte3 >> 6);
if (isNaN(byte3)) {
enc4 = 64;
}
else {
enc4 = byte3 & 63;
}
}
outputStr += b64.charAt(enc1) + b64.charAt(enc2) + b64.charAt(enc3) + b64.charAt(enc4);
}
return outputStr;
}
public showNextRadarFrame(): boolean {
let genDate = this.radialRadarProduct1.showRadarFrame(this.loopIndex);
this.radialRadarProduct2.showRadarFrame(this.loopIndex);
this.render();
let genDateTime = document.getElementById('generationDate');
genDateTime.innerHTML = "Generated On: " + genDate;
this.loopIndex++;
if (this.loopIndex >= this.radialRadarProduct1.getNumberOfActors()) {
this.loopIndex = 0;
return true;
}
else {
return false;
}
}
public processNewRadarProduct(p1: any, view: number) {
if (view === 2) {
this.radialRadarProduct2.processNewRadarProduct(p1);
} else {
this.radialRadarProduct1.processNewRadarProduct(p1);
}
}
private computeGlobePoint(theta, phi, radius): number {
// Lets keep this conversion code in a single place.
let tmp = Math.cos(vtkMath.radiansFromDegrees(phi));
let n0 = -tmp * Math.sin(vtkMath.radiansFromDegrees(theta));
let n1 = tmp * Math.cos(vtkMath.radiansFromDegrees(theta));
let n2 = Math.sin(vtkMath.radiansFromDegrees(phi));
var v = vec3.fromValues(n0 * radius, n1 * radius, n2 * radius);
return v;
}
}
export = RadarRenderWindow;