void drawRadarTextLine(DrawWindow dw, String txt, float x, float y) { float padw = 4, padh = 2; float w = dw.getTextWidth(txt) + padw * 2; float h = dw.getTextAscent() + dw.getTextDescent() + padh * 2; dw.setColor(Color.rgb(0, 0, 0)); dw.setFill(true); dw.drawRectangle(x - w / 2, y - h / 2, w, h); dw.setColor(Color.rgb(255, 255, 255)); dw.setFill(false); dw.drawRectangle(x - w / 2, y - h / 2, w, h); dw.drawText(padw + x - w / 2, padh + dw.getTextAscent() + y - h / 2, txt); }
public void drawDimension(DrawWindow dw) { cam.transform.setTo(ctx.getRotationMatrix()); state.setCurFix(ctx.getCurrentLocation()); // Determine bearing // TODO: fix math rotationInv.setTo(cam.transform); rotationInv.transpose(); looking.setTo(1, 0, 0); looking.transform(rotationInv); state.setCurBearing(ARXUtil.getAngle(0, 0, looking.x, looking.z)); state.setCurBearing(((int) state.getCurBearing() + 360) % 360); // Determine pitch // TODO: fix math rotationInv.transpose(); looking.setTo(0, 1, 0); looking.transform(rotationInv); state.setCurPitch(-ARXUtil.getAngle(0, 0, looking.y, looking.z)); state.setScreenWidth(width); state.setScreenHeight(height); if (ctx.getLaunchUrl().equals("") || ctx.getLaunchUrl().equals(state.getLaunchUrl())) { state.setLaunchNeeded(false); } // Load Layer if (state.getNextLayerStatus() == ARXState.NOT_STARTED || (state.getNextLayerStatus() == ARXState.READY && state.isLaunchNeeded())) { /* * DownloadJobRequest request = new DownloadJobRequest(); * request.format = ARXDownload.GAMADIM; request.url = REDIRECT_URL; * request.cacheable = false; * * state.launchNeeded = false; state.launchUrl = ctx.getLaunchUrl(); * if (!state.launchUrl.equals("")) request.params = * state.getParams("init","NULL") + "&url=" + state.launchUrl; else * request.params = state.getParams("init","NULL"); * * state.downloadJobId = ctx.getARXDownload().submitJob(request); * * state.nextLayerStatus = ARXState.JOB_SUBMITTED; */ String requestUrl; if (!ctx.getLaunchUrl().equals("")) { requestUrl = ctx.getLaunchUrl(); } else { requestUrl = HOME_URL; } DownloadJobRequest request = new DownloadJobRequest( ARXDownload.GAMADIM, requestUrl, state.getParams("init", "NULL"), false); state.setLaunchNeeded(false); state.setLaunchUrl(ctx.getLaunchUrl()); state.setDownloadJobId(ctx.getARXDownload().submitJob(request)); state.setNextLayerStatus(ARXState.JOB_SUBMITTED); } if (state.getNextLayerStatus() == ARXState.JOB_SUBMITTED) { ARXMessages.putMessage( "LOADING_" + state.getDownloadJobId(), "Dimension loading", ARXMessages.refreshIcon, 500); if (ctx.getARXDownload().isJobComplete(state.getDownloadJobId())) { state.setDownloadResult(ctx.getARXDownload().getJobResult(state.getDownloadJobId())); state.setNextLayerStatus(ARXState.TRANSITION); } } if (state.getNextLayerStatus() == ARXState.TRANSITION) { ctx.getARXDownload().pause(); ctx.getARXRender().pause(); if (ctx.getARXDownload().getState() == ARXDownload.PAUSED && ctx.getARXRender().getState() == ARXRender.PAUSED) { if (state.getDownloadResult().isError()) { if (state.getRetryCount() < 10) { ARXMessages.removeMessage("LOADING_" + state.getDownloadJobId()); ARXMessages.removeMessage("ERROR_" + state.getDownloadJobId()); DownloadJobRequest request = new DownloadJobRequest( ARXDownload.GAMADIM, state.getDownloadResult().getErrorRequest().getUrl(), state.getDownloadResult().getErrorRequest().getParams(), state.getDownloadResult().getErrorRequest().isCacheable()); state.setDownloadJobId(ctx.getARXDownload().submitJob(request)); state.setNextLayerStatus(ARXState.JOB_SUBMITTED); state.setRetryCount(state.getRetryCount() + 1); ARXMessages.putMessage( "ERROR_" + state.getDownloadJobId(), "Error: " + state.getDownloadResult().getErrorMsg(), ARXMessages.warningIcon, Integer.MAX_VALUE); ARXMessages.putMessage( "LOADING_" + state.getDownloadJobId(), "Dimension loading (retry #" + state.getRetryCount() + ")", ARXMessages.refreshIcon, Integer.MAX_VALUE); } else { state.setNextLayerStatus(ARXState.READY); state.setLayer(new Layer()); ARXMessages.removeMessage("LOADING_" + state.getDownloadJobId()); ARXMessages.putMessage( "FATAL_ERROR_" + state.getDownloadJobId(), "Unable to load dimension: " + state.getDownloadResult().getErrorRequest().getUrl(), ARXMessages.errorIcon, Integer.MAX_VALUE); } } else { // Layer oldLayer = state.layer; Layer newLayer = (Layer) state.getDownloadResult().getObj(); ARXMessages.removeMessage("ERROR_" + state.getDownloadJobId()); ARXMessages.removeMessage("LOADING_" + state.getDownloadJobId()); // ARXMessages.putMessage("LOADING_COMPLETE_" + // state.downloadJobId, // "Dimension '" + newLayer.xmlName + "' loaded", // ARXMessages.refreshCompleteIcon, 3000); // Clean up ARXRender and ARXDownload ctx.getARXDownload().clearLists(); ctx.getARXRender().clearLists(); // Transfer valid renders for (Placemark pm : state.getLayer().getZOrderedPlacemarks()) { if (pm instanceof Placemark3D) { Placemark3D src = (Placemark3D) pm; Placemark3D dest = (Placemark3D) newLayer.getPlacemark(src.xmlId); if (dest != null) { src.copyRenderState(dest); } } } // Transfer valid downloads for (Asset das : state.getLayer().getAssets()) { Asset dest = (Asset) newLayer.getAsset(das.xmlId); if (dest != null) { das.copyDownloadState(dest); } } // Set layer creation time and location newLayer.creationTime = System.currentTimeMillis(); newLayer.creationLoc.setTo(state.getCurFix()); // Show radar if available if (newLayer.xmlRadarAvailable) state.setRadarVisible(true); if (newLayer.xmlHasRadarRange) radarDialog.setRange(newLayer.xmlRadarRange); state.setLayer(newLayer); state.setNextLayerStatus(ARXState.READY); state.setRetryCount(0); } ctx.getARXDownload().restart(); ctx.getARXRender().restart(); } } for (Placemark pm : state.getLayer().getZOrderedPlacemarks()) { // Update placemarks pm.updateState(state.getCurFix(), System.currentTimeMillis()); // Prepare placemarks for draw pm.prepareDraw(cam); } // Draw placemarks for (Placemark pm : state.getLayer().getZOrderedPlacemarks()) { pm.draw(dw); } // Update asset download status for (Asset das : state.getLayer().getAssets()) { das.isDownloadJobActive = false; if (das.downloadStatus == ARXState.JOB_SUBMITTED) { String activeJobId = ctx.getARXDownload().getActiveJobId(); if (das.downloadJobId.equals(activeJobId)) { das.isDownloadJobActive = true; das.downloadJobPctComplete = ctx.getARXDownload().getActiveJobPctComplete(); String pctTxt = ARXUtil.formatDecimal(das.downloadJobPctComplete * 100, 2); ARXMessages.putMessage( "DOWNLOAD_ASSET", "Downloading '" + das.xmlId + "' (" + pctTxt + "%)", "[" + pctTxt + "%]", ARXMessages.downloadIcon, 500, true); } } } if (state.getNextLayerStatus() == ARXState.READY) { // Update renders for (Placemark pm : state.getLayer().getZOrderedPlacemarks()) { if (pm instanceof Placemark3D) { ((Placemark3D) pm).updateRenders(cam, ctx); } } // Handle show actions for (Overlay ovl : state.getLayer().getOverlays()) { ovl.setShow(false); } float minDist = Float.MAX_VALUE; Placemark closestPM = null; for (Placemark pm : state.getLayer().getZOrderedPlacemarks()) { if (minDist > pm.distToCenter && pm.distToCenter < 50 && pm.xmlShowOnFocus != null) { minDist = pm.distToCenter; closestPM = pm; } } if (closestPM != null) { String ovlIds[] = closestPM.xmlShowOnFocus.split(","); for (int i = 0; i < ovlIds.length; i++) { Overlay ovl = (Overlay) state.getLayer().overlayMap.get(ovlIds[i].trim()); if (ovl != null) ovl.setShow(true); } } // Draw Overlays for (Overlay ovl : state.getLayer().getOverlays()) { if (ovl.isVisible()) ovl.draw(dw); } // Request asset downloads boolean allAssetsDownloaded = true; for (Asset das : state.getLayer().getAssets()) { das.isDownloadJobActive = false; if (das.downloadStatus == ARXState.NOT_STARTED) { DownloadJobRequest request = new DownloadJobRequest(das.xmlFormat, das.xmlUrl, null, true); das.downloadJobId = ctx.getARXDownload().submitJob(request); das.downloadStatus = ARXState.JOB_SUBMITTED; allAssetsDownloaded = false; } else if (das.downloadStatus == ARXState.JOB_SUBMITTED) { if (ctx.getARXDownload().isJobComplete(das.downloadJobId)) { das.downloadResult = ctx.getARXDownload().getJobResult(das.downloadJobId); das.downloadStatus = ARXState.READY; if (!das.downloadResult.isError()) { ARXMessages.putMessage( "DOWNLOAD_ASSET", "Download of '" + das.xmlId + "' complete", "", ARXMessages.downloadCompleteIcon, 500, true); } else { ARXMessages.putMessage( "DOWNLOAD_" + das.downloadJobId, "Error downloading '" + das.xmlId + "'", "", ARXMessages.downloadErrorIcon, 10000, true); } } else { String activeJobId = ctx.getARXDownload().getActiveJobId(); if (das.downloadJobId.equals(activeJobId)) { das.isDownloadJobActive = true; das.downloadJobPctComplete = ctx.getARXDownload().getActiveJobPctComplete(); String pctTxt = ARXUtil.formatDecimal(das.downloadJobPctComplete * 100, 2); ARXMessages.putMessage( "DOWNLOAD_ASSET", "Downloading '" + das.xmlId + "' (" + ARXUtil.formatDecimal(das.downloadJobPctComplete * 100, 2) + "%)", "[" + pctTxt + "%]", ARXMessages.downloadIcon, 500, true); } } allAssetsDownloaded = false; } } // Set assetDownloadTime if (allAssetsDownloaded && !state.getLayer().allAssetsDownloaded) { state.getLayer().allAssetsDownloaded = true; state.getLayer().assetDownloadTime = System.currentTimeMillis(); ARXMessages.putMessage( "ASSETS_LOADING_COMPLETE", "Dimension '" + state.getLayer().xmlName + "' loaded", "", ARXMessages.refreshCompleteIcon, 3000, true); } if (!allAssetsDownloaded) { ARXMessages.putMessage( "ASSETS_LOADING", "Dimension '" + state.getLayer().xmlName + "' loading", ARXMessages.refreshIcon, 500); } } // Draw Radar if (state.isRadarVisible() && state.getLayer().xmlRadarAvailable) { String dirTxt = ""; int bearing = (int) state.getCurBearing(); int range = (int) (state.getCurBearing() / (360f / 16f)); if (range == 15 || range == 0) dirTxt = "N"; else if (range == 1 || range == 2) dirTxt = "NE"; else if (range == 3 || range == 4) dirTxt = "E"; else if (range == 5 || range == 6) dirTxt = "SE"; else if (range == 7 || range == 8) dirTxt = "S"; else if (range == 9 || range == 10) dirTxt = "SW"; else if (range == 11 || range == 12) dirTxt = "W"; else if (range == 13 || range == 14) dirTxt = "NW"; radarObjects.state = state; radarObjects.range = radarDialog.getRange(); dw.drawObject(radarObjects, radarX, radarY, -state.getCurBearing(), 1); dw.setFill(false); dw.setColor(Color.argb(150, 0, 220, 0)); dw.drawLine( leftRadarLine.x, leftRadarLine.y, radarX + RadarObjects.RADIUS, radarY + RadarObjects.RADIUS); dw.drawLine( rightRadarLine.x, rightRadarLine.y, radarX + RadarObjects.RADIUS, radarY + RadarObjects.RADIUS); dw.setColor(Color.rgb(255, 255, 255)); dw.setFontSize(12); drawRadarTextLine( dw, ARXUtil.formatDistance(radarDialog.getRange()), radarX + RadarObjects.RADIUS, radarY + RadarObjects.RADIUS * 2 + 5); drawRadarTextLine( dw, "" + bearing + ((char) 176) + " " + dirTxt, radarX + RadarObjects.RADIUS, radarY - 5); } // Check for time and distance refresh if (state.getNextLayerStatus() == ARXState.READY) { String evtName = null; if (state.getLayer().refreshOnDistance(state.getCurFix())) evtName = "refreshOnDistance"; if (state.getLayer().refreshOnTime(System.currentTimeMillis())) evtName = "refreshOnTime"; if (evtName != null) { DownloadJobRequest request = new DownloadJobRequest( ARXDownload.GAMADIM, state.getLayer().xmlRefreshUrl, state.getParams(evtName, "NULL"), false); state.setDownloadJobId(ctx.getARXDownload().submitJob(request)); state.setNextLayerStatus(ARXState.JOB_SUBMITTED); } } // Get next event Event evt = null; synchronized (events) { if (events.size() > 0) { evt = (Event) events.get(0); events.remove(0); } } if (evt != null && evt.type == Event.MENU) { handleMenuEvent((MenuEvent) evt); evt = null; } if (dialogState == INFO_DIALOG) { dw.setFontSize(12); float infoPad = 50, infoInnerPad = 10; float infoLineHeight = dw.getTextAscent() + dw.getTextDescent(); float infoCurY = infoPad + infoInnerPad + dw.getTextAscent(), infoCurX = infoPad + infoInnerPad; float infoX = infoPad, infoY = infoPad, infoW = width - infoPad * 2, infoH = infoLineHeight * 10 + infoInnerPad * 2; dw.setColor(Color.rgb(0, 0, 0)); dw.setFill(true); dw.drawRectangle(infoX, infoY, infoW, infoH); dw.setColor(Color.rgb(255, 255, 255)); dw.setFill(false); dw.drawRectangle(infoX, infoY, infoW, infoH); String refreshDistanceTxt = ARXUtil.formatDistance((float) state.getLayer().calcRefreshDistance(state.getCurFix())); String validRangeTxt = (state.getLayer().xmlHasRefreshDistance) ? ARXUtil.formatDistance(state.getLayer().xmlValidWithinRange) : "NA"; String refreshTimeTxt = ((System.currentTimeMillis() - state.getLayer().creationTime) / 1000) + "s"; String validForTxt = (state.getLayer().xmlHasRefreshTime) ? (state.getLayer().xmlValidFor / 1000) + "s" : "NA"; dw.drawText(infoCurX, infoCurY, "Dimension: " + state.getLayer().xmlName); infoCurY += infoLineHeight * 2; dw.drawText(infoCurX, infoCurY, "Latitude: " + state.getCurFix().lat); infoCurY += infoLineHeight; dw.drawText(infoCurX, infoCurY, "Longitude: " + state.getCurFix().lon); infoCurY += infoLineHeight; dw.drawText( infoCurX, infoCurY, "Altitude: " + ARXUtil.formatDistance((float) state.getCurFix().alt)); infoCurY += infoLineHeight; dw.drawText(infoCurX, infoCurY, "Bearing: " + state.getCurBearing() + ((char) 176)); infoCurY += infoLineHeight; dw.drawText(infoCurX, infoCurY, "Declination: " + ctx.getDeclination() + ((char) 176)); infoCurY += infoLineHeight; dw.drawText( infoCurX, infoCurY, "Refresh Distance: " + refreshDistanceTxt + "/" + validRangeTxt); infoCurY += infoLineHeight; dw.drawText(infoCurX, infoCurY, "Refresh Time: " + refreshTimeTxt + "/" + validForTxt); infoCurY += infoLineHeight; dw.drawText(infoCurX, infoCurY, "Version: " + VERSION); infoCurY += infoLineHeight; if (evt != null && evt.type == Event.KEY) dialogState = NO_DIALOG; } else if (dialogState == RADAR_DIALOG) { float radarDialogX = width / 2 - radarDialog.getWidth() / 2; float radarDialogY = height / 2 - radarDialog.getHeight() / 2; dw.drawObject(radarDialog, radarDialogX, radarDialogY, 0, 1); if (evt != null && evt.type == Event.CLICK && state.isRadarVisible() && state.getLayer().xmlRadarAvailable) { ClickEvent radarEvt = new ClickEvent( ((ClickEvent) evt).x - radarDialogX, ((ClickEvent) evt).y - radarDialogY); radarDialog.doAccept = false; radarDialog.handleEvent(radarEvt); if (radarDialog.doAccept) dialogState = NO_DIALOG; } } else { if (evt != null && evt.type == Event.CLICK) { handleClickEvent((ClickEvent) evt); } } }