mirror of
https://github.com/Dejvino/roadtrip
synced 2024-11-21 23:42:35 +00:00
Map: refactored populating of map objects to use the new procedural blocks.
This commit is contained in:
parent
7893ff412b
commit
4a87dbc674
@ -90,70 +90,8 @@ public class RoadTrip extends GameApplication implements ActionListener {
|
||||
al.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
|
||||
rootNode.addLight(al);
|
||||
|
||||
gameWorldState = new GameWorldState();
|
||||
gameWorldView = GameWorldView.create(gameWorldState, assetManager, cam, rootNode);
|
||||
final TerrainGrid terrainGrid = gameWorldView.terrain.terrainGrid;
|
||||
terrainGrid.addListener(new TerrainGridListener() {
|
||||
|
||||
@Override
|
||||
public void gridMoved(Vector3f newCenter) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tileAttached(Vector3f cell, TerrainQuad quad) {
|
||||
while(quad.getControl(RigidBodyControl.class)!=null){
|
||||
quad.removeControl(RigidBodyControl.class);
|
||||
}
|
||||
quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrainGrid.getLocalScale()), 0));
|
||||
getPhysicsSpace().add(quad);
|
||||
|
||||
String treesKey = "trees-" + quad.getName();
|
||||
Spatial treesOld = rootNode.getChild(treesKey);
|
||||
if (treesOld != null) {
|
||||
getPhysicsSpace().removeAll(treesOld);
|
||||
treesOld.removeFromParent();
|
||||
}
|
||||
|
||||
Node trees = new Node(treesKey);
|
||||
Random quadRand = new Random(treesKey.hashCode());
|
||||
Spatial treeModel = assetManager.loadModel("Models/tree.j3o");
|
||||
System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale());
|
||||
System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation());
|
||||
float cellSize = terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f;
|
||||
for (int i = 0; i < quadRand.nextInt(1000); i++) {
|
||||
Vector2f pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize)
|
||||
.addLocal(quad.getWorldTranslation().x, quad.getWorldTranslation().z);
|
||||
float height = quad.getHeight(pos);
|
||||
Vector3f location = new Vector3f(pos.x, height, pos.y)
|
||||
.addLocal(terrainGrid.getWorldTranslation());
|
||||
System.out.println("Tree " + i + ": " + location);
|
||||
Spatial treeInstance = treeModel.clone();
|
||||
treeInstance.setLocalTranslation(location);
|
||||
//RigidBodyControl control = treeInstance.getControl(RigidBodyControl.class);
|
||||
RigidBodyControl control = new RigidBodyControl(new ConeCollisionShape(1f, 5f), 0f);
|
||||
if (control != null) {
|
||||
treeInstance.addControl(control);
|
||||
control.setPhysicsLocation(location);
|
||||
getPhysicsSpace().add(control);
|
||||
}
|
||||
trees.attachChild(treeInstance);
|
||||
}
|
||||
rootNode.attachChild(trees);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tileDetached(Vector3f cell, TerrainQuad quad) {
|
||||
if (quad.getControl(RigidBodyControl.class) != null) {
|
||||
getPhysicsSpace().remove(quad);
|
||||
quad.removeControl(RigidBodyControl.class);
|
||||
String treesKey = "trees-" + quad.getName();
|
||||
Spatial trees = rootNode.getChild(treesKey);
|
||||
getPhysicsSpace().removeAll(trees);
|
||||
trees.removeFromParent();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
gameWorldState = new GameWorldState(1L);
|
||||
gameWorldView = GameWorldView.create(gameWorldState, assetManager, cam, rootNode, getPhysicsSpace());
|
||||
|
||||
addCar();
|
||||
addCar();
|
||||
@ -172,7 +110,7 @@ public class RoadTrip extends GameApplication implements ActionListener {
|
||||
|
||||
addTarget();
|
||||
addCompass();
|
||||
addGameMenu();
|
||||
addGameMenu();
|
||||
|
||||
chaseCam = new ChaseCamera(cam, player.node, inputManager);
|
||||
chaseCam.setDefaultDistance(60f);
|
||||
|
@ -39,7 +39,7 @@ public abstract class AbstractProceduralBlock implements ProceduralBlock
|
||||
{
|
||||
if (subBlockClass == null) throw new NullPointerException("subBlockClass");
|
||||
try {
|
||||
Constructor<T> constructor = subBlockClass.getConstructor(Long.class);
|
||||
Constructor<T> constructor = subBlockClass.getConstructor(Long.TYPE);
|
||||
return constructor.newInstance(getSubBlockSeed(subBlockKey));
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalArgumentException("Class " + subBlockClass + " does not have the default constructor with a single 'long' parameter.", e);
|
||||
|
12
src/roadtrip/model/ProceduralMapQuadBlock.java
Normal file
12
src/roadtrip/model/ProceduralMapQuadBlock.java
Normal file
@ -0,0 +1,12 @@
|
||||
package roadtrip.model;
|
||||
|
||||
/**
|
||||
* Created by dejvino on 21.01.2017.
|
||||
*/
|
||||
public class ProceduralMapQuadBlock extends AbstractProceduralBlock
|
||||
{
|
||||
public ProceduralMapQuadBlock(long seed)
|
||||
{
|
||||
super(seed);
|
||||
}
|
||||
}
|
@ -1,12 +1,16 @@
|
||||
package roadtrip.view;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.bullet.PhysicsSpace;
|
||||
import com.jme3.bullet.collision.shapes.ConeCollisionShape;
|
||||
import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
|
||||
import com.jme3.bullet.control.RigidBodyControl;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.Vector2f;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.terrain.geomipmap.*;
|
||||
import com.jme3.terrain.geomipmap.grid.FractalTileLoader;
|
||||
import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator;
|
||||
@ -19,31 +23,36 @@ 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 roadtrip.model.ProceduralMapQuadBlock;
|
||||
import roadtrip.model.TerrainDataProvider;
|
||||
import roadtrip.view.model.GameWorldState;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Created by dejvino on 14.01.2017.
|
||||
*/
|
||||
public class GameWorldView {
|
||||
|
||||
private GameWorldState state;
|
||||
private final GameWorldState state;
|
||||
|
||||
private AssetManager assetManager;
|
||||
private Camera camera;
|
||||
private Node rootNode;
|
||||
private final AssetManager assetManager;
|
||||
private final Camera camera;
|
||||
private final Node rootNode;
|
||||
private final PhysicsSpace physicsSpace;
|
||||
|
||||
public TerrainView terrain = new TerrainView(new TerrainDataProvider());
|
||||
|
||||
public GameWorldView(GameWorldState gameWorldState, AssetManager assetManager, Camera camera, Node rootNode) {
|
||||
public GameWorldView(GameWorldState gameWorldState, AssetManager assetManager, Camera camera, Node rootNode, PhysicsSpace physicsSpace) {
|
||||
this.state = gameWorldState;
|
||||
this.assetManager = assetManager;
|
||||
this.camera = camera;
|
||||
this.rootNode = rootNode;
|
||||
this.physicsSpace = physicsSpace;
|
||||
}
|
||||
|
||||
public static GameWorldView create(GameWorldState gameWorldState, AssetManager assetManager, Camera camera, Node rootNode) {
|
||||
GameWorldView gameWorldView = new GameWorldView(gameWorldState, assetManager, camera, rootNode);
|
||||
public static GameWorldView create(GameWorldState gameWorldState, AssetManager assetManager, Camera camera, Node rootNode, PhysicsSpace physicsSpace) {
|
||||
GameWorldView gameWorldView = new GameWorldView(gameWorldState, assetManager, camera, rootNode, physicsSpace);
|
||||
gameWorldView.initialize();
|
||||
return gameWorldView;
|
||||
}
|
||||
@ -134,5 +143,88 @@ public class GameWorldView {
|
||||
TerrainLodControl control = new TerrainGridLodControl(terrain.terrainGrid, camera);
|
||||
control.setLodCalculator(new DistanceLodCalculator(64 + 1, 2.7f)); // patch size, and a multiplier
|
||||
terrain.terrainGrid.addControl(control);
|
||||
|
||||
final TerrainGrid terrainGrid = terrain.terrainGrid;
|
||||
terrainGrid.addListener(new TerrainGridListener() {
|
||||
|
||||
@Override
|
||||
public void gridMoved(Vector3f newCenter) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tileAttached(Vector3f cell, TerrainQuad quad) {
|
||||
while(quad.getControl(RigidBodyControl.class)!=null){
|
||||
quad.removeControl(RigidBodyControl.class);
|
||||
}
|
||||
quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), terrainGrid.getLocalScale()), 0));
|
||||
physicsSpace.add(quad);
|
||||
|
||||
removeQuadObjectsNode(quad);
|
||||
|
||||
String quadObjectsNodeKey = getQuadObjectsNodeKey(quad);
|
||||
Node objects = new Node(quadObjectsNodeKey);
|
||||
populateQuadObjectsNode(quad, quadObjectsNodeKey, objects);
|
||||
rootNode.attachChild(objects);
|
||||
}
|
||||
|
||||
protected void populateQuadObjectsNode(TerrainQuad quad, String quadObjectsNodeKey, Node objects)
|
||||
{
|
||||
ProceduralMapQuadBlock mapQuadBlock = state.proceduralMap.getMapQuadBlock(quad.getName());
|
||||
|
||||
// TODO: move any access to the Random into the ProceduralMapQuadBlock
|
||||
Random quadRand = mapQuadBlock.getBlockRandom();
|
||||
|
||||
// Generate trees
|
||||
Spatial treeModel = assetManager.loadModel("Models/tree.j3o");
|
||||
//System.out.println("Grid @ " + terrainGrid.getLocalTranslation() + " s " + terrainGrid.getLocalScale());
|
||||
//System.out.println("Quad " + quad.getName() + " @ " + quad.getLocalTranslation());
|
||||
float cellSize = terrainGrid.getPatchSize() * terrainGrid.getLocalScale().x * 2f;
|
||||
for (int i = 0; i < quadRand.nextInt(1000); i++) {
|
||||
Vector2f pos = new Vector2f((quadRand.nextFloat() - 0.5f) * cellSize, (quadRand.nextFloat() - 0.5f) * cellSize)
|
||||
.addLocal(quad.getWorldTranslation().x, quad.getWorldTranslation().z);
|
||||
float height = quad.getHeight(pos);
|
||||
Vector3f location = new Vector3f(pos.x, height, pos.y)
|
||||
.addLocal(terrainGrid.getWorldTranslation());
|
||||
System.out.println("Tree " + i + ": " + location);
|
||||
Spatial treeInstance = treeModel.clone();
|
||||
treeInstance.setLocalTranslation(location);
|
||||
// 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) {
|
||||
treeInstance.addControl(control);
|
||||
control.setPhysicsLocation(location);
|
||||
physicsSpace.add(control);
|
||||
}
|
||||
objects.attachChild(treeInstance);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tileDetached(Vector3f cell, TerrainQuad quad) {
|
||||
if (quad.getControl(RigidBodyControl.class) != null) {
|
||||
physicsSpace.remove(quad);
|
||||
quad.removeControl(RigidBodyControl.class);
|
||||
}
|
||||
removeQuadObjectsNode(quad);
|
||||
}
|
||||
|
||||
protected void removeQuadObjectsNode(TerrainQuad quad)
|
||||
{
|
||||
Spatial quadObjectsNodeOld = rootNode.getChild(getQuadObjectsNodeKey(quad));
|
||||
if (quadObjectsNodeOld != null) {
|
||||
physicsSpace.removeAll(quadObjectsNodeOld);
|
||||
quadObjectsNodeOld.removeFromParent();
|
||||
}
|
||||
}
|
||||
|
||||
private String getQuadObjectsNodeKey(TerrainQuad quad)
|
||||
{
|
||||
return "Objects-" + quad.getName();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,13 @@ import java.util.List;
|
||||
/**
|
||||
* Created by dejvino on 14.01.2017.
|
||||
*/
|
||||
public class GameWorldState {
|
||||
public List<VehicleNode> vehicles = new LinkedList<>();
|
||||
public class GameWorldState
|
||||
{
|
||||
public final ProceduralMapBlock proceduralMap;
|
||||
public final List<VehicleNode> vehicles = new LinkedList<>();
|
||||
|
||||
public GameWorldState(long worldSeed)
|
||||
{
|
||||
this.proceduralMap = new ProceduralMapBlock(worldSeed);
|
||||
}
|
||||
}
|
||||
|
20
src/roadtrip/view/model/ProceduralMapBlock.java
Normal file
20
src/roadtrip/view/model/ProceduralMapBlock.java
Normal file
@ -0,0 +1,20 @@
|
||||
package roadtrip.view.model;
|
||||
|
||||
import roadtrip.model.AbstractProceduralBlock;
|
||||
import roadtrip.model.ProceduralMapQuadBlock;
|
||||
|
||||
/**
|
||||
* Created by dejvino on 21.01.2017.
|
||||
*/
|
||||
public class ProceduralMapBlock extends AbstractProceduralBlock
|
||||
{
|
||||
public ProceduralMapBlock(long seed)
|
||||
{
|
||||
super(seed);
|
||||
}
|
||||
|
||||
public ProceduralMapQuadBlock getMapQuadBlock(String quadName)
|
||||
{
|
||||
return getSubBlock(quadName, ProceduralMapQuadBlock.class);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user