diff --git a/assets/Models/house1.j3o b/assets/Models/house1.j3o new file mode 100644 index 0000000..1fab6d1 Binary files /dev/null and b/assets/Models/house1.j3o differ diff --git a/assets/Models/house1.j3odata b/assets/Models/house1.j3odata new file mode 100644 index 0000000..6281864 --- /dev/null +++ b/assets/Models/house1.j3odata @@ -0,0 +1,3 @@ +# +#Wed Jan 25 22:21:44 CET 2017 +ORIGINAL_PATH=Models/house1.scene diff --git a/assets/Models/tree.j3o b/assets/Models/tree.j3o index f6ea1de..e0fc3fe 100644 Binary files a/assets/Models/tree.j3o and b/assets/Models/tree.j3o differ diff --git a/assets/Models/tree.j3odata b/assets/Models/tree.j3odata index a05c058..6c543c5 100644 --- a/assets/Models/tree.j3odata +++ b/assets/Models/tree.j3odata @@ -1,3 +1,3 @@ # -#Fri Jan 20 22:43:12 CET 2017 +#Thu Jan 26 22:04:15 CET 2017 ORIGINAL_PATH=Models/tree.scene diff --git a/src/roadtrip/RoadTrip.java b/src/roadtrip/RoadTrip.java index cbf6848..1d1078f 100644 --- a/src/roadtrip/RoadTrip.java +++ b/src/roadtrip/RoadTrip.java @@ -1,14 +1,7 @@ package roadtrip; -import com.jme3.audio.AudioNode; -import com.jme3.audio.AudioSource.Status; -import com.jme3.bullet.collision.shapes.*; import com.jme3.bullet.control.BetterCharacterControl; -import com.jme3.bullet.control.RigidBodyControl; import com.jme3.bullet.control.VehicleControl; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.font.Rectangle; import com.jme3.input.ChaseCamera; import com.jme3.input.KeyInput; import com.jme3.input.controls.ActionListener; @@ -17,17 +10,10 @@ import com.jme3.light.AmbientLight; import com.jme3.light.DirectionalLight; import com.jme3.material.Material; import com.jme3.math.*; -import com.jme3.renderer.queue.RenderQueue; import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.Spatial; -import com.jme3.scene.debug.Arrow; import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Cylinder; -import com.jme3.terrain.geomipmap.TerrainGrid; -import com.jme3.terrain.geomipmap.TerrainGridListener; -import com.jme3.terrain.geomipmap.TerrainQuad; -import java.util.Random; import roadtrip.model.VehicleInstance; import roadtrip.view.CompassNode; import roadtrip.view.GameMenuNode; diff --git a/src/roadtrip/RoadTripPlanner.java b/src/roadtrip/RoadTripPlanner.java index a987d80..90e8d01 100644 --- a/src/roadtrip/RoadTripPlanner.java +++ b/src/roadtrip/RoadTripPlanner.java @@ -1,43 +1,11 @@ package roadtrip; import com.jme3.app.SimpleApplication; -import com.jme3.audio.AudioNode; -import com.jme3.audio.AudioSource.Status; import com.jme3.bullet.BulletAppState; import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.collision.shapes.*; -import com.jme3.bullet.control.BetterCharacterControl; -import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.control.VehicleControl; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.font.Rectangle; -import com.jme3.input.ChaseCamera; -import com.jme3.input.KeyInput; -import com.jme3.input.controls.ActionListener; -import com.jme3.input.controls.KeyTrigger; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; import com.jme3.math.*; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.debug.Arrow; -import com.jme3.scene.shape.Box; -import com.jme3.scene.shape.Cylinder; -import com.jme3.terrain.geomipmap.TerrainGrid; -import com.jme3.terrain.geomipmap.TerrainGridListener; -import com.jme3.terrain.geomipmap.TerrainQuad; -import java.util.Random; -import roadtrip.model.VehicleInstance; -import roadtrip.view.CompassNode; -import roadtrip.view.GameMenuNode; import roadtrip.view.GameWorldView; -import roadtrip.view.VehicleNode; import roadtrip.view.model.GameWorldState; -import roadtrip.view.model.Player; /** * @@ -73,5 +41,7 @@ public class RoadTripPlanner extends SimpleApplication { flyCam.setMoveSpeed(300f); cam.setLocation(new Vector3f(0, 200f, 0)); + cam.setFrustumNear(1f); + cam.setFrustumFar(3000f); } } diff --git a/src/roadtrip/model/MapObjectInstance.java b/src/roadtrip/model/MapObjectInstance.java index 6ea927b..5042eba 100644 --- a/src/roadtrip/model/MapObjectInstance.java +++ b/src/roadtrip/model/MapObjectInstance.java @@ -8,10 +8,12 @@ import com.jme3.math.Vector3f; public class MapObjectInstance { private Vector3f position; + private String type; - public MapObjectInstance(Vector3f position) + public MapObjectInstance(String type, Vector3f position) { - this.position = new Vector3f(position); + this.type = type; + this.position = new Vector3f(position); } public Vector3f getPosition() @@ -23,4 +25,8 @@ public class MapObjectInstance { this.position = new Vector3f(position); } + + public String getType() { + return type; + } } diff --git a/src/roadtrip/model/ProceduralMapQuadBlock.java b/src/roadtrip/model/ProceduralMapQuadBlock.java index 62360c6..65053f4 100644 --- a/src/roadtrip/model/ProceduralMapQuadBlock.java +++ b/src/roadtrip/model/ProceduralMapQuadBlock.java @@ -17,8 +17,6 @@ import java.util.Random; */ public class ProceduralMapQuadBlock extends AbstractProceduralBlock { - protected float cellSize = 64 * 2f * 2f; /* terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f */ - private List mapObjects; public ProceduralMapQuadBlock(long seed) @@ -28,23 +26,30 @@ public class ProceduralMapQuadBlock extends AbstractProceduralBlock public void initialize(TerrainQuad terrainQuad) { + float cellSize = terrainQuad.getPatchSize() * 8f * terrainQuad.getLocalScale().x * 2f; mapObjects = new LinkedList<>(); Random quadRand = getBlockRandom(); Vector2f prevPos = null; - Vector2f quadPos = new Vector2f(terrainQuad.getLocalTranslation().x, terrainQuad.getLocalTranslation().z); - for (int i = 0; i < quadRand.nextInt(100); i++) { + Vector2f quadPos = new Vector2f(terrainQuad.getWorldTranslation().x, terrainQuad.getWorldTranslation().z); + for (int i = 0; i < quadRand.nextInt(terrainQuad.getPatchSize() * terrainQuad.getPatchSize()); i++) { Vector2f pos; if (prevPos == null || quadRand.nextFloat() < 0.2f) { pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize) .addLocal(quadPos); } else { - pos = new Vector2f((quadRand.nextFloat() - 0.5f) * 20f, (quadRand.nextFloat() - 0.5f) * 20f) + pos = new Vector2f((quadRand.nextFloat() - 0.5f) * (cellSize / 10f), (quadRand.nextFloat() - 0.5f) * (cellSize / 10f)) .addLocal(prevPos); } prevPos = pos; float height = terrainQuad.getHeight(pos); + String type; + if (quadRand.nextInt(10) == 0) { + type = "house"; + } else { + type = "tree"; + } Vector3f location = new Vector3f(pos.x, height, pos.y); - mapObjects.add(new MapObjectInstance(location)); + mapObjects.add(new MapObjectInstance(type, location)); } } diff --git a/src/roadtrip/view/GameWorldView.java b/src/roadtrip/view/GameWorldView.java index cfba70a..6f4a4f4 100644 --- a/src/roadtrip/view/GameWorldView.java +++ b/src/roadtrip/view/GameWorldView.java @@ -2,6 +2,7 @@ package roadtrip.view; import com.jme3.asset.AssetManager; import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.shapes.BoxCollisionShape; import com.jme3.bullet.collision.shapes.ConeCollisionShape; import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; import com.jme3.bullet.control.RigidBodyControl; @@ -9,6 +10,7 @@ import com.jme3.light.AmbientLight; import com.jme3.light.DirectionalLight; import com.jme3.material.Material; import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; import com.jme3.scene.Node; @@ -26,6 +28,7 @@ import com.jme3.terrain.noise.filter.SmoothFilter; import com.jme3.terrain.noise.fractal.FractalSum; import com.jme3.terrain.noise.modulator.NoiseModulator; import com.jme3.texture.Texture; +import java.util.Random; import roadtrip.model.MapObjectInstance; import roadtrip.model.ProceduralMapQuadBlock; import roadtrip.model.TerrainDataProvider; @@ -78,7 +81,7 @@ public class GameWorldView { terrain.mat_terrain.getAdditionalRenderState().setWireframe(true); } - float heightScale = 100f; + float heightScale = 400f; // Parameters to material: // regionXColorMap: X = 1..4 the texture that should be appliad to state X @@ -117,10 +120,10 @@ public class GameWorldView { terrain.mat_terrain.setFloat("terrainSize", 513); terrain.terrainDataProvider.base = new FractalSum(); - terrain.terrainDataProvider.base.setRoughness(0.7f); + terrain.terrainDataProvider.base.setRoughness(0.6f); terrain.terrainDataProvider.base.setFrequency(1.0f); terrain.terrainDataProvider.base.setAmplitude(1.0f); - terrain.terrainDataProvider.base.setLacunarity(2.12f); + terrain.terrainDataProvider.base.setLacunarity(4.12f); terrain.terrainDataProvider.base.setOctaves(8); terrain.terrainDataProvider.base.setScale(0.02125f); terrain.terrainDataProvider.base.addModulator(new NoiseModulator() { @@ -142,7 +145,7 @@ public class GameWorldView { terrain.terrainDataProvider.smooth = new SmoothFilter(); terrain.terrainDataProvider.smooth.setRadius(1); - terrain.terrainDataProvider.smooth.setEffect(0.7f); + terrain.terrainDataProvider.smooth.setEffect(0.3f); terrain.terrainDataProvider.iterate = new IterativeFilter(); terrain.terrainDataProvider.iterate.addPreFilter(terrain.terrainDataProvider.perturb); @@ -152,13 +155,14 @@ public class GameWorldView { ground.addPreFilter(terrain.terrainDataProvider.iterate); - int patchSize = 32; + int patchSize = 16; + Vector3f terrainScale = new Vector3f(8f, 1f, 8f); //terrain.terrainGrid = new TerrainGrid("terrain", 16 + 1, 512 + 1, new FractalTileLoader(ground, 300f)); - terrain.terrainGrid = new FineTerrainGrid("terrain", patchSize + 1, 512 + 1, new FractalTileLoader(ground, heightScale)); + terrain.terrainGrid = new FineTerrainGrid("terrain", patchSize + 1, 128 + 1, terrainScale, new FractalTileLoader(ground, heightScale)); terrain.terrainGrid.setMaterial(terrain.mat_terrain); //terrain.terrainGrid.setLocalTranslation(0, -200, 0); - //terrain.terrainGrid.setLocalScale(2f, 1f, 2f); + terrain.terrainGrid.setLocalScale(terrainScale); this.rootNode.attachChild(terrain.terrainGrid); final TerrainLodControl lodControl = new FineTerrainGridLodControl(terrain.terrainGrid, camera); @@ -166,6 +170,7 @@ public class GameWorldView { terrain.terrainGrid.addControl(lodControl); final Spatial treeModel = assetManager.loadModel("Models/tree.j3o"); + final Spatial houseModel = assetManager.loadModel("Models/house1.j3o"); final FineTerrainGrid terrainGrid = terrain.terrainGrid; terrainGrid.addListener(new TerrainGridListener() { @@ -188,6 +193,7 @@ public class GameWorldView { String quadObjectsNodeKey = getQuadObjectsNodeKey(quad); Node objects = new Node(quadObjectsNodeKey); populateQuadObjectsNode(quad, objects); + System.out.println("Add quad " + quad.getName()); rootNode.attachChild(objects); } @@ -195,24 +201,50 @@ public class GameWorldView { { ProceduralMapQuadBlock mapQuadBlock = state.proceduralMap.getMapQuadBlock(quad); - // Add map objects (for now - trees) - //System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale()); - //System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation()); + /*/ DEBUG pole in the middle of a quad + Spatial m = treeModel.clone(); + m.setLocalTranslation(quad.getWorldTranslation().add(new Vector3f(0f, getHeight(quad, quad.getWorldTranslation()), 0f))); + m.setLocalScale(new Vector3f(1f, 20f, 1f)); + objects.attachChild(m); + /**/ + + // Add map objects + Random rand = mapQuadBlock.getBlockRandom(); for (MapObjectInstance mapObject : mapQuadBlock.getMapObjects()) { Vector3f pos = mapObject.getPosition(); - Spatial modelInstance = treeModel.clone(); + Vector3f scale = Vector3f.UNIT_XYZ; + Vector3f boxHalf = Vector3f.UNIT_XYZ; + Spatial modelInstance; + RigidBodyControl modelPhysics; + switch (mapObject.getType()) { + case "tree": + modelInstance = treeModel.clone(); + float s = 0.2f + rand.nextFloat() * 5f; + scale = new Vector3f(s, s, s); + boxHalf = new Vector3f(s * 0.2f, s * 3f, s * 0.2f); + modelPhysics = new RigidBodyControl(new BoxCollisionShape(boxHalf), 0f); + break; + case "house": + modelInstance = houseModel.clone(); + boxHalf = new Vector3f(2f + rand.nextFloat() * 10f, 2f + rand.nextFloat() * 10f, 2f + rand.nextFloat() * 10f); + scale = boxHalf; + modelPhysics = new RigidBodyControl(new BoxCollisionShape(boxHalf), 0f); + break; + default: + throw new RuntimeException("Unhandled object type: " + mapObject.getType()); + } modelInstance.setLocalTranslation(pos); + modelInstance.setLocalScale(scale); // TODO: physics from the model and not hard-coded //RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class); - RigidBodyControl control = new RigidBodyControl(new ConeCollisionShape(1f, 5f), 0f); - if (control != null) { - modelInstance.addControl(control); - control.setPhysicsLocation(pos); - //physicsSpace.add(control); + if (modelPhysics != null) { + modelPhysics.isActive(); + modelInstance.addControl(modelPhysics); + modelPhysics.setPhysicsLocation(pos); + physicsSpace.add(modelPhysics); } objects.attachChild(modelInstance); } - //objects.setLocalTranslation(terrainGrid.getWorldTranslation()); } @Override @@ -222,6 +254,7 @@ public class GameWorldView { quad.removeControl(RigidBodyControl.class); } removeQuadObjectsNode(quad); + System.out.println("Del quad " + quad.getName()); } protected void removeQuadObjectsNode(TerrainQuad quad) @@ -238,6 +271,10 @@ public class GameWorldView { return "Objects-" + quad.getName(); } + private float getHeight(TerrainQuad quad, Vector3f pos) + { + return quad.getHeight(new Vector2f(pos.x, pos.z)); + } }); /**/