private void adjustHeight(Vector3f loc, float radius, float height) { // offset it by radius because in the loop we iterate through 2 radii int radiusStepsX = (int) (radius / terrain.getLocalScale().x); int radiusStepsZ = (int) (radius / terrain.getLocalScale().z); float xStepAmount = terrain.getLocalScale().x; float zStepAmount = terrain.getLocalScale().z; long start = System.currentTimeMillis(); List<Vector2f> locs = new ArrayList<Vector2f>(); List<Float> heights = new ArrayList<Float>(); for (int z = -radiusStepsZ; z < radiusStepsZ; z++) { for (int x = -radiusStepsX; x < radiusStepsX; x++) { float locX = loc.x + (x * xStepAmount); float locZ = loc.z + (z * zStepAmount); if (isInRadius(locX - loc.x, locZ - loc.z, radius)) { // see if it is in the radius of the tool float h = calculateHeight(radius, height, locX - loc.x, locZ - loc.z); locs.add(new Vector2f(locX, locZ)); heights.add(h); } } } terrain.adjustHeight(locs, heights); // System.out.println("Modified "+locs.size()+" points, took: " + (System.currentTimeMillis() - // start)+" ms"); terrain.updateModelBound(); }
@Override public void simpleUpdate(float tpf) { Vector3f intersection = getWorldIntersection(); updateHintText(intersection); if (raiseTerrain) { if (intersection != null) { adjustHeight(intersection, 64, tpf * 60); } } else if (lowerTerrain) { if (intersection != null) { adjustHeight(intersection, 64, -tpf * 60); } } if (terrain != null && intersection != null) { float h = terrain.getHeight(new Vector2f(intersection.x, intersection.z)); Vector3f tl = terrain.getWorldTranslation(); marker.setLocalTranslation(tl.add(new Vector3f(intersection.x, h, intersection.z))); markerNormal.setLocalTranslation(tl.add(new Vector3f(intersection.x, h, intersection.z))); Vector3f normal = terrain.getNormal(new Vector2f(intersection.x, intersection.z)); ((Arrow) markerNormal.getMesh()).setArrowExtent(normal); } }
@Override public void simpleInitApp() { /** 1. Create terrain material and load four textures into it. */ mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md"); /** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */ mat_terrain.setTexture( "Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); /** 1.2) Add GRASS texture into the red layer (Tex1). */ Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); grass.setWrap(WrapMode.Repeat); mat_terrain.setTexture("Tex1", grass); mat_terrain.setFloat("Tex1Scale", 64f); /** 1.3) Add DIRT texture into the green layer (Tex2) */ Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); dirt.setWrap(WrapMode.Repeat); mat_terrain.setTexture("Tex2", dirt); mat_terrain.setFloat("Tex2Scale", 32f); /** 1.4) Add ROAD texture into the blue layer (Tex3) */ Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); rock.setWrap(WrapMode.Repeat); mat_terrain.setTexture("Tex3", rock); mat_terrain.setFloat("Tex3Scale", 128f); /** 2. Create the height map */ AbstractHeightMap heightmap = null; Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); heightmap = new ImageBasedHeightMap(heightMapImage.getImage()); heightmap.load(); /** * 3. We have prepared material and heightmap. Now we create the actual terrain: 3.1) Create a * TerrainQuad and name it "my terrain". 3.2) A good value for terrain tiles is 64x64 -- so we * supply 64+1=65. 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513. 3.4) * As LOD step scale we supply Vector3f(1,1,1). 3.5) We supply the prepared heightmap itself. */ int patchSize = 65; terrain = new TerrainQuad("my terrain", patchSize, 513, heightmap.getHeightMap()); /** 4. We give the terrain its material, position & scale it, and attach it. */ terrain.setMaterial(mat_terrain); terrain.setLocalTranslation(0, -100, 0); terrain.setLocalScale(2f, 1f, 2f); rootNode.attachChild(terrain); /** 5. The LOD (level of detail) depends on were the camera is: */ TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); terrain.addControl(control); inputManager.removeListener(flyCam); final RTSCam rtsCam = new RTSCam(cam, rootNode); rtsCam.registerWithInput(inputManager); rtsCam.setCenter(new Vector3f(0, 5f, 0)); }
public Terrain(MonkeyWar war) { /** 1. Create terrain material and load four textures into it. */ material = new Material(war.getAssetManager(), "Common/MatDefs/Terrain/Terrain.j3md"); /** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */ material.setTexture( "Alpha", war.getAssetManager().loadTexture("Textures/Terrain/splat/alphamap.png")); /** 1.2) Add GRASS texture into the red layer (Tex1). */ Texture grass = war.getAssetManager().loadTexture("Textures/Terrain/splat/grass.jpg"); grass.setWrap(WrapMode.Repeat); material.setTexture("Tex1", grass); material.setFloat("Tex1Scale", 64f); /** 1.3) Add DIRT texture into the green layer (Tex2) */ Texture dirt = war.getAssetManager().loadTexture("Textures/Terrain/splat/dirt.jpg"); dirt.setWrap(WrapMode.Repeat); material.setTexture("Tex2", dirt); material.setFloat("Tex2Scale", 32f); /** 1.4) Add ROAD texture into the blue layer (Tex3) */ Texture rock = war.getAssetManager().loadTexture("Textures/Terrain/splat/road.jpg"); rock.setWrap(WrapMode.Repeat); material.setTexture("Tex3", rock); material.setFloat("Tex3Scale", 128f); /** 2. Create the height map */ AbstractHeightMap heightmap = null; Texture heightMapImage = war.getAssetManager().loadTexture("Textures/Terrain/splat/mountains512.png"); heightmap = new ImageBasedHeightMap(heightMapImage.getImage()); heightmap.load(); /** * 3. We have prepared material and heightmap. Now we create the actual terrain: 3.1) Create a * TerrainQuad and name it "my terrain". 3.2) A good value for terrain tiles is 64x64 -- so we * supply 64+1=65. 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513. 3.4) * As LOD step scale we supply Vector3f(1,1,1). 3.5) We supply the prepared heightmap itself. */ int patchSize = 65; quad = new TerrainQuad("my terrain", patchSize, 513, heightmap.getHeightMap()); /** 4. We give the terrain its material, position & scale it, and attach it. */ quad.setMaterial(material); quad.setLocalScale(2f, 1f, 2f); Terrain.node.attachChild(quad); /** 5. The LOD (level of detail) depends on were the camera is: */ TerrainLodControl lod = new TerrainLodControl(quad, war.getCamera()); quad.addControl(lod); /** ATTACH THE TERRAIN CONTROL TO THE TERRAIN */ quad.addControl(this); }
private void createTerrain() { // First, we load up our textures and the heightmap texture for the terrain // TERRAIN TEXTURE material matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); matTerrain.setBoolean("useTriPlanarMapping", false); matTerrain.setBoolean("WardIso", true); matTerrain.setFloat("Shininess", 0); // ALPHA map (for splat textures) matTerrain.setTexture( "AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); // GRASS texture Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); grass.setWrap(WrapMode.Repeat); matTerrain.setTexture("DiffuseMap", grass); matTerrain.setFloat("DiffuseMap_0_scale", grassScale); // DIRT texture Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); dirt.setWrap(WrapMode.Repeat); matTerrain.setTexture("DiffuseMap_1", dirt); matTerrain.setFloat("DiffuseMap_1_scale", dirtScale); // ROCK texture Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); rock.setWrap(WrapMode.Repeat); matTerrain.setTexture("DiffuseMap_2", rock); matTerrain.setFloat("DiffuseMap_2_scale", rockScale); // HEIGHTMAP image (for the terrain heightmap) Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); AbstractHeightMap heightmap = null; try { heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.5f); heightmap.load(); heightmap.smooth(0.9f, 1); } catch (Exception e) { e.printStackTrace(); } // CREATE THE TERRAIN terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); control.setLodCalculator(new DistanceLodCalculator(65, 2.7f)); // patch size, and a multiplier terrain.addControl(control); terrain.setMaterial(matTerrain); terrain.setLocalTranslation(0, -100, 0); terrain.setLocalScale(2.5f, 0.5f, 2.5f); rootNode.attachChild(terrain); }
public void onAction(String name, boolean pressed, float tpf) { if (name.equals("wireframe") && !pressed) { wireframe = !wireframe; if (!wireframe) { terrain.setMaterial(matWire); } else { terrain.setMaterial(matTerrain); } } else if (name.equals("Raise")) { raiseTerrain = pressed; } else if (name.equals("Lower")) { lowerTerrain = pressed; } }
public void loadTerrain() { try { long start = System.currentTimeMillis(); // remove the existing terrain and detach it from the root node. if (terrain != null) { Node existingTerrain = (Node) terrain; existingTerrain.removeFromParent(); existingTerrain.removeControl(TerrainLodControl.class); existingTerrain.detachAllChildren(); terrain = null; } InputStream fis = game.getGameApplication() .getAssetManager() .locateAsset(new AssetKey("Scenes/" + map + "/terrainsave.jme")) .openStream(); BinaryImporter imp = BinaryImporter.getInstance(); imp.setAssetManager(assetManager); terrain = (TerrainQuad) imp.load(new BufferedInputStream(fis)); terrain.setShadowMode(ShadowMode.CastAndReceive); clickableNode.attachChild((Node) terrain); float duration = (System.currentTimeMillis() - start) / 1000.0f; System.out.println("Load took " + duration + " seconds"); } catch (Exception e) { } }
private Vector3f getWorldIntersection() { Vector3f origin = cam.getWorldCoordinates( new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f); Vector3f direction = cam.getWorldCoordinates( new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f); direction.subtractLocal(origin).normalizeLocal(); Ray ray = new Ray(origin, direction); CollisionResults results = new CollisionResults(); int numCollisions = terrain.collideWith(ray, results); if (numCollisions > 0) { CollisionResult hit = results.getClosestCollision(); return hit.getContactPoint(); } return null; }
@Override public void simpleInitApp() { /** Set up Physics */ bulletAppState = new BulletAppState(); stateManager.attach(bulletAppState); // bulletAppState.getPhysicsSpace().enableDebug(assetManager); flyCam.setMoveSpeed(100); setUpKeys(); /** 1. Create terrain material and load four textures into it. */ mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md"); /** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */ mat_terrain.setTexture( "Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); /** 1.2) Add GRASS texture into the red layer (Tex1). */ Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); grass.setWrap(WrapMode.Repeat); mat_terrain.setTexture("Tex1", grass); mat_terrain.setFloat("Tex1Scale", 64f); /** 1.3) Add DIRT texture into the green layer (Tex2) */ Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); dirt.setWrap(WrapMode.Repeat); mat_terrain.setTexture("Tex2", dirt); mat_terrain.setFloat("Tex2Scale", 32f); /** 1.4) Add ROAD texture into the blue layer (Tex3) */ Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); rock.setWrap(WrapMode.Repeat); mat_terrain.setTexture("Tex3", rock); mat_terrain.setFloat("Tex3Scale", 128f); /** 2. Create the height map */ AbstractHeightMap heightmap = null; Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); heightmap = new ImageBasedHeightMap(heightMapImage.getImage()); heightmap.load(); /** * 3. We have prepared material and heightmap. Now we create the actual terrain: 3.1) Create a * TerrainQuad and name it "my terrain". 3.2) A good value for terrain tiles is 64x64 -- so we * supply 64+1=65. 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513. 3.4) * As LOD step scale we supply Vector3f(1,1,1). 3.5) We supply the prepared heightmap itself. */ terrain = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap()); /** 4. We give the terrain its material, position & scale it, and attach it. */ terrain.setMaterial(mat_terrain); terrain.setLocalTranslation(0, -100, 0); terrain.setLocalScale(2f, 1f, 2f); rootNode.attachChild(terrain); /** 5. The LOD (level of detail) depends on were the camera is: */ List<Camera> cameras = new ArrayList<Camera>(); cameras.add(getCamera()); TerrainLodControl control = new TerrainLodControl(terrain, cameras); terrain.addControl(control); /** 6. Add physics: */ /* We set up collision detection for the scene by creating a static * RigidBodyControl with mass zero.*/ terrain.addControl(new RigidBodyControl(0)); // We set up collision detection for the player by creating // a capsule collision shape and a CharacterControl. // The CharacterControl offers extra settings for // size, stepheight, jumping, falling, and gravity. // We also put the player in its starting position. CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1); player = new CharacterControl(capsuleShape, 0.05f); player.setJumpSpeed(20); player.setFallSpeed(30); player.setGravity(30); player.setPhysicsLocation(new Vector3f(-10, 10, 10)); // We attach the scene and the player to the rootnode and the physics space, // to make them appear in the game world. bulletAppState.getPhysicsSpace().add(terrain); bulletAppState.getPhysicsSpace().add(player); }
private void createTerrainGrid() { // TERRAIN TEXTURE material matTerrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md"); // Parameters to material: // regionXColorMap: X = 1..4 the texture that should be appliad to state X // regionX: a Vector3f containing the following information: // regionX.x: the start height of the region // regionX.y: the end height of the region // regionX.z: the texture scale for the region // it might not be the most elegant way for storing these 3 values, but it packs the data // nicely :) // slopeColorMap: the texture to be used for cliffs, and steep mountain sites // slopeTileFactor: the texture scale for slopes // terrainSize: the total size of the terrain (used for scaling the texture) // GRASS texture Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); grass.setWrap(WrapMode.Repeat); matTerrain.setTexture("region1ColorMap", grass); matTerrain.setVector3("region1", new Vector3f(88, 200, this.grassScale)); // DIRT texture Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); dirt.setWrap(WrapMode.Repeat); matTerrain.setTexture("region2ColorMap", dirt); matTerrain.setVector3("region2", new Vector3f(0, 90, this.dirtScale)); // ROCK texture Texture rock = assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg"); rock.setWrap(WrapMode.Repeat); matTerrain.setTexture("region3ColorMap", rock); matTerrain.setVector3("region3", new Vector3f(198, 260, this.rockScale)); matTerrain.setTexture("region4ColorMap", rock); matTerrain.setVector3("region4", new Vector3f(198, 260, this.rockScale)); matTerrain.setTexture("slopeColorMap", rock); matTerrain.setFloat("slopeTileFactor", 32); matTerrain.setFloat("terrainSize", 513); FractalSum base = new FractalSum(); base.setRoughness(0.7f); base.setFrequency(1.0f); base.setAmplitude(1.0f); base.setLacunarity(2.12f); base.setOctaves(8); base.setScale(0.02125f); base.addModulator( new NoiseModulator() { @Override public float value(float... in) { return ShaderUtils.clamp(in[0] * 0.5f + 0.5f, 0, 1); } }); FilteredBasis ground = new FilteredBasis(base); PerturbFilter perturb = new PerturbFilter(); perturb.setMagnitude(0.119f); OptimizedErode therm = new OptimizedErode(); therm.setRadius(5); therm.setTalus(0.011f); SmoothFilter smooth = new SmoothFilter(); smooth.setRadius(1); smooth.setEffect(0.7f); IterativeFilter iterate = new IterativeFilter(); iterate.addPreFilter(perturb); iterate.addPostFilter(smooth); iterate.setFilter(therm); iterate.setIterations(1); ground.addPreFilter(iterate); this.terrain = new TerrainGrid("terrain", 65, 257, new FractalTileLoader(ground, 256f)); terrain.setMaterial(matTerrain); terrain.setLocalTranslation(0, 0, 0); terrain.setLocalScale(2f, 1f, 2f); rootNode.attachChild(this.terrain); TerrainLodControl control = new TerrainLodControl(this.terrain, getCamera()); this.terrain.addControl(control); }
/** Business logic */ public static MotionPath createMotionPath( TerrainQuad terrain, Cell[][] cells, Cell from, Cell to, Creature creature) throws NoReachablePathException { if (creature instanceof AirborneCreature) { AirborneCreature airCreature = (AirborneCreature) creature; airCreature.takeOff(); } if (!to.creatureAllowed(creature)) { throw new NoReachablePathException(); } MotionPath motionPath = new MotionPath(); /** Different for air creatures */ if (creature instanceof AirborneCreature) { // Add take off waypoint Vector3f takeOffWayPoint = new Vector3f( from.getWorldCoordinates().x, airCreatureHeight, from.getWorldCoordinates().z); motionPath.addWayPoint(creature.getModel().getLocalTranslation()); motionPath.addWayPoint(takeOffWayPoint); int numSteps = 100; float diffX = (to.getWorldCoordinates().x - from.getWorldCoordinates().x) / (float) numSteps; float diffZ = (to.getWorldCoordinates().z - from.getWorldCoordinates().z) / (float) numSteps; for (int i = 0; i < numSteps; i++) { float x = from.getWorldCoordinates().x + i * diffX; float z = from.getWorldCoordinates().z + i * diffZ; // float y = terrain.getHeight(new Vector2f(x, z)) + airCreatureHeight; motionPath.addWayPoint(new Vector3f(x, airCreatureHeight, z)); } } else { List<Cell> findPath = findPath(cells, from, to, creature); Cell previousCell = null; for (Cell cell : findPath) { if (previousCell != null) { // Smoothen path int numParts = 5; float xDiff = (cell.getWorldCoordinates().x - previousCell.getWorldCoordinates().x) / (float) numParts; float zDiff = (cell.getWorldCoordinates().z - previousCell.getWorldCoordinates().z) / (float) numParts; for (int i = 0; i < numParts; i++) { float x = previousCell.getWorldCoordinates().x + i * xDiff; float z = previousCell.getWorldCoordinates().z + i * zDiff; Vector3f part = null; if (creature instanceof SeaCreature) { System.out.println("test"); part = new Vector3f(x, 0, z); } else { part = new Vector3f(x, terrain.getHeight(new Vector2f(x, z)) - 100, z); } motionPath.addWayPoint(part); } } if (creature instanceof SeaCreature) { Vector3f old = cell.getWorldCoordinates(); motionPath.addWayPoint( new Vector3f(old.x, creature.getModel().getLocalTranslation().y, old.z)); } else { motionPath.addWayPoint(cell.getWorldCoordinates()); } previousCell = cell; } } motionPath.setCycle(false); return motionPath; }