159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/* 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved. 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met: 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer. 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * notice, this list of conditions and the following disclaimer in the 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * documentation and/or other materials provided with the distribution. 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * may be used to endorse or promote products derived from this software 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * without specific prior written permission. 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage jme3test.terrain; 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.app.SimpleApplication; 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.Savable; 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.binary.BinaryExporter; 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.binary.BinaryImporter; 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.font.BitmapText; 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.KeyInput; 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.controls.ActionListener; 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.input.controls.KeyTrigger; 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.light.DirectionalLight; 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.material.Material; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.ColorRGBA; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f; 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Node; 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.Terrain; 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.geomipmap.TerrainLodControl; 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.geomipmap.TerrainQuad; 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.heightmap.AbstractHeightMap; 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.terrain.heightmap.ImageBasedHeightMap; 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Texture; 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.texture.Texture.WrapMode; 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.*; 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Level; 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger; 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/** 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Saves and loads terrain. 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Brent Owens 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class TerrainTestReadWrite extends SimpleApplication { 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private Terrain terrain; 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected BitmapText hintText; 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float grassScale = 64; 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float dirtScale = 16; 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private float rockScale = 128; 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private Material matTerrain; 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private Material matWire; 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static void main(String[] args) { 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TerrainTestReadWrite app = new TerrainTestReadWrite(); 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta app.start(); 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //testHeightmapBuilding(); 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void initialize() { 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super.initialize(); 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta loadHintText(); 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void simpleInitApp() { 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta createControls(); 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta createMap(); 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private void createMap() { 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setBoolean("useTriPlanarMapping", false); 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setBoolean("WardIso", true); 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // ALPHA map (for splat textures) 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // HEIGHTMAP image (for the terrain heightmap) 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // GRASS texture 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta grass.setWrap(WrapMode.Repeat); 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setTexture("DiffuseMap", grass); 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setFloat("DiffuseMap_0_scale", grassScale); 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // DIRT texture 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta dirt.setWrap(WrapMode.Repeat); 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setTexture("DiffuseMap_1", dirt); 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setFloat("DiffuseMap_1_scale", dirtScale); 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // ROCK texture 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rock.setWrap(WrapMode.Repeat); 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setTexture("DiffuseMap_2", rock); 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setFloat("DiffuseMap_2_scale", rockScale); 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normalMap0.setWrap(WrapMode.Repeat); 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normalMap1.setWrap(WrapMode.Repeat); 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta normalMap2.setWrap(WrapMode.Repeat); 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setTexture("NormalMap", normalMap0); 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setTexture("NormalMap_1", normalMap2); 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matTerrain.setTexture("NormalMap_2", normalMap2); 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matWire.getAdditionalRenderState().setWireframe(true); 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta matWire.setColor("Color", ColorRGBA.Green); 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // CREATE HEIGHTMAP 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta AbstractHeightMap heightmap = null; 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta try { 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 1f); 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta heightmap.load(); 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } catch (Exception e) { 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta e.printStackTrace(); 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (new File("terrainsave.jme").exists()) { 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta loadTerrain(); 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // create the terrain as normal, and give it a control for LOD management 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TerrainQuad terrainQuad = new TerrainQuad("terrain", 65, 129, heightmap.getHeightMap());//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TerrainLodControl control = new TerrainLodControl(terrainQuad, getCamera()); 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta terrainQuad.addControl(control); 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta terrainQuad.setMaterial(matTerrain); 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta terrainQuad.setLocalTranslation(0, -100, 0); 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta terrainQuad.setLocalScale(4f, 0.25f, 4f); 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rootNode.attachChild(terrainQuad); 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.terrain = terrainQuad; 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta DirectionalLight light = new DirectionalLight(); 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize()); 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rootNode.addLight(light); 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Create the save and load actions and add them to the input listener 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private void createControls() { 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta flyCam.setMoveSpeed(50); 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta cam.setLocation(new Vector3f(0, 100, 0)); 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta inputManager.addMapping("save", new KeyTrigger(KeyInput.KEY_T)); 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta inputManager.addListener(saveActionListener, "save"); 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta inputManager.addMapping("load", new KeyTrigger(KeyInput.KEY_Y)); 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta inputManager.addListener(loadActionListener, "load"); 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta inputManager.addMapping("clone", new KeyTrigger(KeyInput.KEY_C)); 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta inputManager.addListener(cloneActionListener, "clone"); 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void loadHintText() { 19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta hintText = new BitmapText(guiFont, false); 19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta hintText.setSize(guiFont.getCharSet().getRenderedSize()); 19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta hintText.setLocalTranslation(0, getCamera().getHeight(), 0); 19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta hintText.setText("Hit T to save, and Y to load"); 19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta guiNode.attachChild(hintText); 19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private ActionListener saveActionListener = new ActionListener() { 19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void onAction(String name, boolean pressed, float tpf) { 19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (name.equals("save") && !pressed) { 20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FileOutputStream fos = null; 20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta try { 20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta long start = System.currentTimeMillis(); 20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fos = new FileOutputStream(new File("terrainsave.jme")); 20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // we just use the exporter and pass in the terrain 20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BinaryExporter.getInstance().save((Savable)terrain, new BufferedOutputStream(fos)); 20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fos.flush(); 21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float duration = (System.currentTimeMillis() - start) / 1000.0f; 21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println("Save took " + duration + " seconds"); 21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } catch (IOException ex) { 21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex); 21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } finally { 21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta try { 21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fos != null) { 21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fos.close(); 21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } catch (IOException e) { 22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, e); 22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta }; 22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private void loadTerrain() { 22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta FileInputStream fis = null; 22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta try { 23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta long start = System.currentTimeMillis(); 23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // remove the existing terrain and detach it from the root node. 23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (terrain != null) { 23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Node existingTerrain = (Node)terrain; 23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta existingTerrain.removeFromParent(); 23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta existingTerrain.removeControl(TerrainLodControl.class); 23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta existingTerrain.detachAllChildren(); 23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta terrain = null; 23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // import the saved terrain, and attach it back to the root node 24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta File f = new File("terrainsave.jme"); 24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fis = new FileInputStream(f); 24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta BinaryImporter imp = BinaryImporter.getInstance(); 24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta imp.setAssetManager(assetManager); 24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta terrain = (TerrainQuad) imp.load(new BufferedInputStream(fis)); 24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rootNode.attachChild((Node)terrain); 24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float duration = (System.currentTimeMillis() - start) / 1000.0f; 24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println("Load took " + duration + " seconds"); 25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // now we have to add back the camera to the LOD control 25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TerrainLodControl lodControl = ((Node)terrain).getControl(TerrainLodControl.class); 25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (lodControl != null) 25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta lodControl.setCamera(getCamera()); 25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } catch (IOException ex) { 25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex); 25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } finally { 25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta try { 26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (fis != null) { 26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta fis.close(); 26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } catch (IOException ex) { 26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Logger.getLogger(TerrainTestReadWrite.class.getName()).log(Level.SEVERE, null, ex); 26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private ActionListener loadActionListener = new ActionListener() { 26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void onAction(String name, boolean pressed, float tpf) { 27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (name.equals("load") && !pressed) { 27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta loadTerrain(); 27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta }; 27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private ActionListener cloneActionListener = new ActionListener() { 27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void onAction(String name, boolean pressed, float tpf) { 27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (name.equals("clone") && !pressed) { 28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Terrain clone = (Terrain) ((Node)terrain).clone(); 28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ((Node)terrain).removeFromParent(); 28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta terrain = clone; 28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta getRootNode().attachChild((Node)terrain); 28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta }; 28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // no junit tests, so this has to be hand-tested: 29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private static void testHeightmapBuilding() { 29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int s = 9; 29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int b = 3; 29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float[] hm = new float[s * s]; 29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < s; i++) { 29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int j = 0; j < s; j++) { 29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta hm[(i * s) + j] = i * j; 29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < s; i++) { 30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int j = 0; j < s; j++) { 30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.print(hm[i * s + j] + " "); 30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println(""); 30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta TerrainQuad terrain = new TerrainQuad("terrain", b, s, hm); 30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float[] hm2 = terrain.getHeightMap(); 30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta boolean failed = false; 31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < s * s; i++) { 31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (hm[i] != hm2[i]) { 31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta failed = true; 31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println(""); 31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (failed) { 31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println("Terrain heightmap building FAILED!!!"); 31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int i = 0; i < s; i++) { 32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta for (int j = 0; j < s; j++) { 32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.print(hm2[i * s + j] + " "); 32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println(""); 32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta System.out.println("Terrain heightmap building PASSED"); 32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 330