protected void updateLOD(final SafeArrayList<Vector3f> locations, final LodCalculator lodCalculator) { if (getSpatial() == null || locations.isEmpty()) { return; updateQuadLODs(); if (updateLodOffCount(lodCalculator)) { return; prepareTerrain(); indexer = executorService.submit(createLodUpdateTask(cloneVectorList(locations), lodCalculator));
public TerrainLodControl(final Terrain terrain, final Camera camera) { this(terrain); setCamera(camera); }
/** * Only uses the first camera right now. * @param terrain to act upon (must be a Spatial) * @param cameras one or more cameras to reference for LOD calc */ public TerrainLodControl(final Terrain terrain, final List<Camera> cameras) { this(terrain); setCameras(cameras); }
protected void updateLOD(final LodCalculator lodCalculator) { if (getSpatial() == null || camera == null) { return; } // update any existing ones that need updating updateQuadLODs(); if (updateLodOffCount(lodCalculator)) { return; } final Vector3f currentLocation = camera.getLocation(); if (!forceUpdate && previousCameraLocation.equals(currentLocation) && !lodCalculator.isLodOff()) { return; // don't update if in same spot } else { previousCameraLocation.set(currentLocation); } forceUpdate = false; if (!lodCalcRunning.compareAndSet(false, true)) { return; } prepareTerrain(); final TerrainExecutorService executorService = TerrainExecutorService.getInstance(); indexer = executorService.submit(createLodUpdateTask(singletonList(currentLocation), lodCalculator)); }
TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier terrain.addControl(control); terrain.setMaterial(matTerrain);
protected void updateLOD(List<Vector3f> locations, LodCalculator lodCalculator) { if(getSpatial() == null){ return; updateQuadLODs(); if (!forceUpdate && lastCameraLocationsTheSame(locations) && !lodCalculator.isLodOff()) return; // don't update if in same spot else lastCameraLocations = cloneVectorList(locations); forceUpdate = false; lastCameraLocations = cloneVectorList(locations); return; if (isLodCalcRunning()) { return; setLodCalcRunning(true); executor = createExecutorService(); prepareTerrain(); UpdateLOD updateLodThread = getLodThread(locations, lodCalculator); indexer = executor.submit(updateLodThread);
List<Camera> cameras = new ArrayList<Camera>(); cameras.add(getCamera()); TerrainLodControl control = new TerrainLodControl(terrain, cameras); terrain.addControl(control); terrain.setMaterial(matRock);
TerrainLodControl control = terrain.getControl(TerrainLodControl.class); if (control != null) control.detachAndCleanUpControl(); else { control = new TerrainLodControl(terrain, cam); terrain.addControl(control);
/** * Call this when you remove the terrain or this control from the scene. * It will clear up any threads it had. */ public void detachAndCleanUpControl() { if (indexer != null) { indexer.cancel(true); indexer = null; } getSpatial().removeControl(this); }
control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier this.terrain.addControl(control);
if (isUseRenderCamera()) { updateLOD(lodCalculator); updateLOD(cameraLocations, lodCalculator);
@Override protected void updateLOD(SafeArrayList<Vector3f> locations, LodCalculator lodCalculator) { TerrainGrid terrainGrid = (TerrainGrid)getSpatial(); // for now, only the first camera is handled. // to accept more, there are two ways: // 1: every camera has an associated grid, then the location is not enough to identify which camera location has changed // 2: grids are associated with locations, and no incremental update is done, we load new grids for new locations, and unload those that are not needed anymore Vector3f cam = locations.isEmpty() ? Vector3f.ZERO.clone() : locations.get(0); Vector3f camCell = terrainGrid.getCamCell(cam); // get the grid index value of where the camera is (ie. 2,1) if (terrainGrid.cellsLoaded > 1) { // Check if cells are updated before updating gridoffset. terrainGrid.gridOffset[0] = Math.round(camCell.x * (terrainGrid.size / 2)); terrainGrid.gridOffset[1] = Math.round(camCell.z * (terrainGrid.size / 2)); terrainGrid.cellsLoaded = 0; } if (camCell.x != terrainGrid.currentCamCell.x || camCell.z != terrainGrid.currentCamCell.z || !terrainGrid.runOnce) { // if the camera has moved into a new cell, load new terrain into the visible 4 center quads terrainGrid.updateChildren(camCell); for (TerrainGridListener l : terrainGrid.listeners) { l.gridMoved(camCell); } } terrainGrid.runOnce = true; super.updateLOD(locations, lodCalculator); } }
public HashMap<String, UpdatedTerrainPatch> call() throws Exception { //long start = System.currentTimeMillis(); //if (isLodCalcRunning()) { // return null; //} setLodCalcRunning(true); TerrainQuad terrainQuad = (TerrainQuad)getSpatial(); // go through each patch and calculate its LOD based on camera distance HashMap<String,UpdatedTerrainPatch> updated = new HashMap<String,UpdatedTerrainPatch>(); boolean lodChanged = terrainQuad.calculateLod(camLocations, updated, lodCalculator); // 'updated' gets populated here if (!lodChanged) { // not worth updating anything else since no one's LOD changed setLodCalcRunning(false); return null; } // then calculate its neighbour LOD values for seaming in the shader terrainQuad.findNeighboursLod(updated); terrainQuad.fixEdges(updated); // 'updated' can get added to here terrainQuad.reIndexPages(updated, lodCalculator.usesVariableLod()); //setUpdateQuadLODs(updated); // set back to main ogl thread setLodCalcRunning(false); return updated; } }
TerrainLodControl control = new TerrainLodControl(terrainQuad, getCamera()); control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier terrainQuad.addControl(control); terrainQuad.setMaterial(matTerrain);
List<Camera> cameras = new ArrayList<Camera>(); cameras.add(getCamera()); TerrainLodControl control = new TerrainLodControl(terrain, cameras); terrain.addControl(control); terrain.setMaterial(matRock);
protected void prepareTerrain() { TerrainQuad terrain = (TerrainQuad) getSpatial(); // cache the terrain's world transforms so they can be accessed on the separate thread safely terrain.cacheTerrainTransforms(); }
control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier this.terrain.addControl(control);
@Override protected void controlUpdate(float tpf) { //list of cameras for when terrain supports multiple cameras (ie split screen) if (lodCalculator == null) return; if (!enabled) { if (!hasResetLod) { // this will get run once hasResetLod = true; lodCalculator.turnOffLod(); } } if (cameras != null) { cameraLocations.clear(); for (Camera c : cameras) // populate them { cameraLocations.add(c.getLocation()); } updateLOD(cameraLocations, lodCalculator); } }
TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); control.setLodCalculator( new DistanceLodCalculator(patchSize, 2.7f) ); // patch size, and a multiplier terrain.addControl(control);
TerrainLodControl control = new TerrainLodControl(terrain, cameras); terrain.addControl(control);