1
0
mirror of https://github.com/Dejvino/roadtrip synced 2024-11-14 13:03:28 +00:00

Map: improved terrain scale, object placement.

This commit is contained in:
Dejvino 2017-01-27 01:42:53 +01:00
parent 33185850a1
commit b828e377b1
9 changed files with 79 additions and 72 deletions

BIN
assets/Models/house1.j3o Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
#
#Wed Jan 25 22:21:44 CET 2017
ORIGINAL_PATH=Models/house1.scene

Binary file not shown.

View File

@ -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 ORIGINAL_PATH=Models/tree.scene

View File

@ -1,14 +1,7 @@
package roadtrip; 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.BetterCharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.control.VehicleControl; 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.ChaseCamera;
import com.jme3.input.KeyInput; import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.ActionListener;
@ -17,17 +10,10 @@ import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight; import com.jme3.light.DirectionalLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.*; import com.jme3.math.*;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.scene.debug.Arrow;
import com.jme3.scene.shape.Box; 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.model.VehicleInstance;
import roadtrip.view.CompassNode; import roadtrip.view.CompassNode;
import roadtrip.view.GameMenuNode; import roadtrip.view.GameMenuNode;

View File

@ -1,43 +1,11 @@
package roadtrip; package roadtrip;
import com.jme3.app.SimpleApplication; 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.BulletAppState;
import com.jme3.bullet.PhysicsSpace; 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.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.GameWorldView;
import roadtrip.view.VehicleNode;
import roadtrip.view.model.GameWorldState; import roadtrip.view.model.GameWorldState;
import roadtrip.view.model.Player;
/** /**
* *
@ -73,5 +41,7 @@ public class RoadTripPlanner extends SimpleApplication {
flyCam.setMoveSpeed(300f); flyCam.setMoveSpeed(300f);
cam.setLocation(new Vector3f(0, 200f, 0)); cam.setLocation(new Vector3f(0, 200f, 0));
cam.setFrustumNear(1f);
cam.setFrustumFar(3000f);
} }
} }

View File

@ -8,9 +8,11 @@ import com.jme3.math.Vector3f;
public class MapObjectInstance public class MapObjectInstance
{ {
private Vector3f position; private Vector3f position;
private String type;
public MapObjectInstance(Vector3f position) public MapObjectInstance(String type, Vector3f position)
{ {
this.type = type;
this.position = new Vector3f(position); this.position = new Vector3f(position);
} }
@ -23,4 +25,8 @@ public class MapObjectInstance
{ {
this.position = new Vector3f(position); this.position = new Vector3f(position);
} }
public String getType() {
return type;
}
} }

View File

@ -17,8 +17,6 @@ import java.util.Random;
*/ */
public class ProceduralMapQuadBlock extends AbstractProceduralBlock public class ProceduralMapQuadBlock extends AbstractProceduralBlock
{ {
protected float cellSize = 64 * 2f * 2f; /* terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f */
private List<MapObjectInstance> mapObjects; private List<MapObjectInstance> mapObjects;
public ProceduralMapQuadBlock(long seed) public ProceduralMapQuadBlock(long seed)
@ -28,23 +26,30 @@ public class ProceduralMapQuadBlock extends AbstractProceduralBlock
public void initialize(TerrainQuad terrainQuad) public void initialize(TerrainQuad terrainQuad)
{ {
float cellSize = terrainQuad.getPatchSize() * 8f * terrainQuad.getLocalScale().x * 2f;
mapObjects = new LinkedList<>(); mapObjects = new LinkedList<>();
Random quadRand = getBlockRandom(); Random quadRand = getBlockRandom();
Vector2f prevPos = null; Vector2f prevPos = null;
Vector2f quadPos = new Vector2f(terrainQuad.getLocalTranslation().x, terrainQuad.getLocalTranslation().z); Vector2f quadPos = new Vector2f(terrainQuad.getWorldTranslation().x, terrainQuad.getWorldTranslation().z);
for (int i = 0; i < quadRand.nextInt(100); i++) { for (int i = 0; i < quadRand.nextInt(terrainQuad.getPatchSize() * terrainQuad.getPatchSize()); i++) {
Vector2f pos; Vector2f pos;
if (prevPos == null || quadRand.nextFloat() < 0.2f) { if (prevPos == null || quadRand.nextFloat() < 0.2f) {
pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize) pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize)
.addLocal(quadPos); .addLocal(quadPos);
} else { } 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); .addLocal(prevPos);
} }
prevPos = pos; prevPos = pos;
float height = terrainQuad.getHeight(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); Vector3f location = new Vector3f(pos.x, height, pos.y);
mapObjects.add(new MapObjectInstance(location)); mapObjects.add(new MapObjectInstance(type, location));
} }
} }

View File

@ -2,6 +2,7 @@ package roadtrip.view;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
import com.jme3.bullet.PhysicsSpace; 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.ConeCollisionShape;
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape; import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
import com.jme3.bullet.control.RigidBodyControl; import com.jme3.bullet.control.RigidBodyControl;
@ -9,6 +10,7 @@ import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight; import com.jme3.light.DirectionalLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import com.jme3.scene.Node; 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.fractal.FractalSum;
import com.jme3.terrain.noise.modulator.NoiseModulator; import com.jme3.terrain.noise.modulator.NoiseModulator;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import java.util.Random;
import roadtrip.model.MapObjectInstance; import roadtrip.model.MapObjectInstance;
import roadtrip.model.ProceduralMapQuadBlock; import roadtrip.model.ProceduralMapQuadBlock;
import roadtrip.model.TerrainDataProvider; import roadtrip.model.TerrainDataProvider;
@ -78,7 +81,7 @@ public class GameWorldView {
terrain.mat_terrain.getAdditionalRenderState().setWireframe(true); terrain.mat_terrain.getAdditionalRenderState().setWireframe(true);
} }
float heightScale = 100f; float heightScale = 400f;
// Parameters to material: // Parameters to material:
// regionXColorMap: X = 1..4 the texture that should be appliad to state X // 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.mat_terrain.setFloat("terrainSize", 513);
terrain.terrainDataProvider.base = new FractalSum(); 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.setFrequency(1.0f);
terrain.terrainDataProvider.base.setAmplitude(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.setOctaves(8);
terrain.terrainDataProvider.base.setScale(0.02125f); terrain.terrainDataProvider.base.setScale(0.02125f);
terrain.terrainDataProvider.base.addModulator(new NoiseModulator() { terrain.terrainDataProvider.base.addModulator(new NoiseModulator() {
@ -142,7 +145,7 @@ public class GameWorldView {
terrain.terrainDataProvider.smooth = new SmoothFilter(); terrain.terrainDataProvider.smooth = new SmoothFilter();
terrain.terrainDataProvider.smooth.setRadius(1); 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 = new IterativeFilter();
terrain.terrainDataProvider.iterate.addPreFilter(terrain.terrainDataProvider.perturb); terrain.terrainDataProvider.iterate.addPreFilter(terrain.terrainDataProvider.perturb);
@ -152,13 +155,14 @@ public class GameWorldView {
ground.addPreFilter(terrain.terrainDataProvider.iterate); 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 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.setMaterial(terrain.mat_terrain);
//terrain.terrainGrid.setLocalTranslation(0, -200, 0); //terrain.terrainGrid.setLocalTranslation(0, -200, 0);
//terrain.terrainGrid.setLocalScale(2f, 1f, 2f); terrain.terrainGrid.setLocalScale(terrainScale);
this.rootNode.attachChild(terrain.terrainGrid); this.rootNode.attachChild(terrain.terrainGrid);
final TerrainLodControl lodControl = new FineTerrainGridLodControl(terrain.terrainGrid, camera); final TerrainLodControl lodControl = new FineTerrainGridLodControl(terrain.terrainGrid, camera);
@ -166,6 +170,7 @@ public class GameWorldView {
terrain.terrainGrid.addControl(lodControl); terrain.terrainGrid.addControl(lodControl);
final Spatial treeModel = assetManager.loadModel("Models/tree.j3o"); final Spatial treeModel = assetManager.loadModel("Models/tree.j3o");
final Spatial houseModel = assetManager.loadModel("Models/house1.j3o");
final FineTerrainGrid terrainGrid = terrain.terrainGrid; final FineTerrainGrid terrainGrid = terrain.terrainGrid;
terrainGrid.addListener(new TerrainGridListener() { terrainGrid.addListener(new TerrainGridListener() {
@ -188,6 +193,7 @@ public class GameWorldView {
String quadObjectsNodeKey = getQuadObjectsNodeKey(quad); String quadObjectsNodeKey = getQuadObjectsNodeKey(quad);
Node objects = new Node(quadObjectsNodeKey); Node objects = new Node(quadObjectsNodeKey);
populateQuadObjectsNode(quad, objects); populateQuadObjectsNode(quad, objects);
System.out.println("Add quad " + quad.getName());
rootNode.attachChild(objects); rootNode.attachChild(objects);
} }
@ -195,24 +201,50 @@ public class GameWorldView {
{ {
ProceduralMapQuadBlock mapQuadBlock = state.proceduralMap.getMapQuadBlock(quad); ProceduralMapQuadBlock mapQuadBlock = state.proceduralMap.getMapQuadBlock(quad);
// Add map objects (for now - trees) /*/ DEBUG pole in the middle of a quad
//System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale()); Spatial m = treeModel.clone();
//System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation()); 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()) { for (MapObjectInstance mapObject : mapQuadBlock.getMapObjects()) {
Vector3f pos = mapObject.getPosition(); 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.setLocalTranslation(pos);
modelInstance.setLocalScale(scale);
// TODO: physics from the model and not hard-coded // TODO: physics from the model and not hard-coded
//RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class); //RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class);
RigidBodyControl control = new RigidBodyControl(new ConeCollisionShape(1f, 5f), 0f); if (modelPhysics != null) {
if (control != null) { modelPhysics.isActive();
modelInstance.addControl(control); modelInstance.addControl(modelPhysics);
control.setPhysicsLocation(pos); modelPhysics.setPhysicsLocation(pos);
//physicsSpace.add(control); physicsSpace.add(modelPhysics);
} }
objects.attachChild(modelInstance); objects.attachChild(modelInstance);
} }
//objects.setLocalTranslation(terrainGrid.getWorldTranslation());
} }
@Override @Override
@ -222,6 +254,7 @@ public class GameWorldView {
quad.removeControl(RigidBodyControl.class); quad.removeControl(RigidBodyControl.class);
} }
removeQuadObjectsNode(quad); removeQuadObjectsNode(quad);
System.out.println("Del quad " + quad.getName());
} }
protected void removeQuadObjectsNode(TerrainQuad quad) protected void removeQuadObjectsNode(TerrainQuad quad)
@ -238,6 +271,10 @@ public class GameWorldView {
return "Objects-" + quad.getName(); return "Objects-" + quad.getName();
} }
private float getHeight(TerrainQuad quad, Vector3f pos)
{
return quad.getHeight(new Vector2f(pos.x, pos.z));
}
}); });
/**/ /**/