1
0
mirror of https://github.com/Dejvino/roadtrip synced 2024-12-22 11:48:49 +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

View File

@ -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;

View File

@ -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);
}
}

View File

@ -8,9 +8,11 @@ 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.type = type;
this.position = new Vector3f(position);
}
@ -23,4 +25,8 @@ public class MapObjectInstance
{
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
{
protected float cellSize = 64 * 2f * 2f; /* terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f */
private List<MapObjectInstance> 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));
}
}

View File

@ -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));
}
});
/**/