1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package jme3test.light; 33 34 import com.jme3.app.SimpleApplication; 35 import com.jme3.bounding.BoundingBox; 36 import com.jme3.font.BitmapText; 37 import com.jme3.light.AmbientLight; 38 import com.jme3.light.PointLight; 39 import com.jme3.light.SpotLight; 40 import com.jme3.material.Material; 41 import com.jme3.math.ColorRGBA; 42 import com.jme3.math.FastMath; 43 import com.jme3.math.Quaternion; 44 import com.jme3.math.Vector3f; 45 import com.jme3.scene.Geometry; 46 import com.jme3.scene.Spatial; 47 import com.jme3.terrain.geomipmap.TerrainLodControl; 48 import com.jme3.terrain.geomipmap.TerrainQuad; 49 import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; 50 import com.jme3.terrain.heightmap.AbstractHeightMap; 51 import com.jme3.terrain.heightmap.ImageBasedHeightMap; 52 import com.jme3.texture.Texture; 53 import com.jme3.texture.Texture.WrapMode; 54 import com.jme3.util.SkyFactory; 55 import jme3tools.converters.ImageToAwt; 56 57 /** 58 * Uses the terrain's lighting texture with normal maps and lights. 59 * 60 * @author bowens 61 */ 62 public class TestSpotLightTerrain extends SimpleApplication { 63 64 private TerrainQuad terrain; 65 Material matTerrain; 66 Material matWire; 67 boolean wireframe = false; 68 boolean triPlanar = false; 69 boolean wardiso = false; 70 boolean minnaert = false; 71 protected BitmapText hintText; 72 PointLight pl; 73 Geometry lightMdl; 74 private float grassScale = 64; 75 private float dirtScale = 16; 76 private float rockScale = 128; 77 SpotLight sl; 78 main(String[] args)79 public static void main(String[] args) { 80 TestSpotLightTerrain app = new TestSpotLightTerrain(); 81 app.start(); 82 } 83 84 85 @Override simpleInitApp()86 public void simpleInitApp() { 87 makeTerrain(); 88 flyCam.setMoveSpeed(50); 89 90 sl = new SpotLight(); 91 sl.setSpotRange(100); 92 sl.setSpotOuterAngle(20 * FastMath.DEG_TO_RAD); 93 sl.setSpotInnerAngle(15 * FastMath.DEG_TO_RAD); 94 sl.setDirection(new Vector3f(-0.39820394f, -0.73094344f, 0.55421597f)); 95 sl.setPosition(new Vector3f(-64.61567f, -87.615425f, -202.41328f)); 96 rootNode.addLight(sl); 97 98 AmbientLight ambLight = new AmbientLight(); 99 ambLight.setColor(new ColorRGBA(0.8f, 0.8f, 0.8f, 0.2f)); 100 rootNode.addLight(ambLight); 101 102 cam.setLocation(new Vector3f(-41.219646f, -84.8363f, -171.67267f)); 103 cam.setRotation(new Quaternion(-0.04562731f, 0.89917684f, -0.09668826f, -0.4243236f)); 104 sl.setDirection(cam.getDirection()); 105 sl.setPosition(cam.getLocation()); 106 107 } 108 109 @Override simpleUpdate(float tpf)110 public void simpleUpdate(float tpf) { 111 super.simpleUpdate(tpf); 112 sl.setDirection(cam.getDirection()); 113 sl.setPosition(cam.getLocation()); 114 115 } 116 makeTerrain()117 private void makeTerrain() { 118 // TERRAIN TEXTURE material 119 matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); 120 matTerrain.setBoolean("useTriPlanarMapping", false); 121 matTerrain.setBoolean("WardIso", true); 122 123 // ALPHA map (for splat textures) 124 matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png")); 125 matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png")); 126 127 // HEIGHTMAP image (for the terrain heightmap) 128 Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); 129 130 131 // GRASS texture 132 Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); 133 grass.setWrap(WrapMode.Repeat); 134 matTerrain.setTexture("DiffuseMap", grass); 135 matTerrain.setFloat("DiffuseMap_0_scale", grassScale); 136 137 // DIRT texture 138 Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); 139 dirt.setWrap(WrapMode.Repeat); 140 matTerrain.setTexture("DiffuseMap_1", dirt); 141 matTerrain.setFloat("DiffuseMap_1_scale", dirtScale); 142 143 // ROCK texture 144 Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); 145 rock.setWrap(WrapMode.Repeat); 146 matTerrain.setTexture("DiffuseMap_2", rock); 147 matTerrain.setFloat("DiffuseMap_2_scale", rockScale); 148 149 // BRICK texture 150 Texture brick = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"); 151 brick.setWrap(WrapMode.Repeat); 152 matTerrain.setTexture("DiffuseMap_3", brick); 153 matTerrain.setFloat("DiffuseMap_3_scale", rockScale); 154 155 // RIVER ROCK texture 156 Texture riverRock = assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg"); 157 riverRock.setWrap(WrapMode.Repeat); 158 matTerrain.setTexture("DiffuseMap_4", riverRock); 159 matTerrain.setFloat("DiffuseMap_4_scale", rockScale); 160 161 162 Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); 163 normalMap0.setWrap(WrapMode.Repeat); 164 Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); 165 normalMap1.setWrap(WrapMode.Repeat); 166 Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); 167 normalMap2.setWrap(WrapMode.Repeat); 168 matTerrain.setTexture("NormalMap", normalMap0); 169 matTerrain.setTexture("NormalMap_1", normalMap2); 170 matTerrain.setTexture("NormalMap_2", normalMap2); 171 matTerrain.setTexture("NormalMap_4", normalMap2); 172 173 // WIREFRAME material 174 matWire = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); 175 matWire.getAdditionalRenderState().setWireframe(true); 176 matWire.setColor("Color", ColorRGBA.Green); 177 178 createSky(); 179 180 // CREATE HEIGHTMAP 181 AbstractHeightMap heightmap = null; 182 try { 183 //heightmap = new HillHeightMap(1025, 1000, 50, 100, (byte) 3); 184 185 heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 1f); 186 heightmap.load(); 187 188 } catch (Exception e) { 189 e.printStackTrace(); 190 } 191 192 terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());//, new LodPerspectiveCalculatorFactory(getCamera(), 4)); // add this in to see it use entropy for LOD calculations 193 TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); 194 control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); 195 terrain.addControl(control); 196 terrain.setMaterial(matTerrain); 197 terrain.setModelBound(new BoundingBox()); 198 terrain.updateModelBound(); 199 terrain.setLocalTranslation(0, -100, 0); 200 terrain.setLocalScale(1f, 1f, 1f); 201 rootNode.attachChild(terrain); 202 } 203 createSky()204 private void createSky() { 205 Texture west = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_west.jpg"); 206 Texture east = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_east.jpg"); 207 Texture north = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_north.jpg"); 208 Texture south = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_south.jpg"); 209 Texture up = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_up.jpg"); 210 Texture down = assetManager.loadTexture("Textures/Sky/Lagoon/lagoon_down.jpg"); 211 212 Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down); 213 rootNode.attachChild(sky); 214 } 215 216 217 } 218