@@ -1,5 +1,6 @@ | |||||
package roadtrip.model; | package roadtrip.model; | ||||
import com.jme3.terrain.geomipmap.LRUCache; | |||||
import java.lang.reflect.Constructor; | import java.lang.reflect.Constructor; | ||||
import java.lang.reflect.InvocationTargetException; | import java.lang.reflect.InvocationTargetException; | ||||
import java.util.Random; | import java.util.Random; | ||||
@@ -11,6 +12,8 @@ public abstract class AbstractProceduralBlock implements ProceduralBlock | |||||
{ | { | ||||
private long seed; | private long seed; | ||||
private LRUCache<String, ProceduralBlock> subBlocksCache = new LRUCache<>(getSubBlocksCacheSize()); | |||||
public AbstractProceduralBlock(long seed) | public AbstractProceduralBlock(long seed) | ||||
{ | { | ||||
this.seed = seed; | this.seed = seed; | ||||
@@ -38,13 +41,24 @@ public abstract class AbstractProceduralBlock implements ProceduralBlock | |||||
public <T extends ProceduralBlock> T getSubBlock(String subBlockKey, Class<T> subBlockClass) | public <T extends ProceduralBlock> T getSubBlock(String subBlockKey, Class<T> subBlockClass) | ||||
{ | { | ||||
if (subBlockClass == null) throw new NullPointerException("subBlockClass"); | if (subBlockClass == null) throw new NullPointerException("subBlockClass"); | ||||
T result = (T) subBlocksCache.get(subBlockKey); | |||||
if (result != null) { | |||||
return result; | |||||
} | |||||
try { | try { | ||||
Constructor<T> constructor = subBlockClass.getConstructor(Long.TYPE); | Constructor<T> constructor = subBlockClass.getConstructor(Long.TYPE); | ||||
return constructor.newInstance(getSubBlockSeed(subBlockKey)); | |||||
result = constructor.newInstance(getSubBlockSeed(subBlockKey)); | |||||
subBlocksCache.put(subBlockKey, result); | |||||
return result; | |||||
} catch (NoSuchMethodException e) { | } catch (NoSuchMethodException e) { | ||||
throw new IllegalArgumentException("Class " + subBlockClass + " does not have the default constructor with a single 'long' parameter.", e); | throw new IllegalArgumentException("Class " + subBlockClass + " does not have the default constructor with a single 'long' parameter.", e); | ||||
} catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { | } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { | ||||
throw new IllegalArgumentException("Unable to instantiate sub-block.", e); | throw new IllegalArgumentException("Unable to instantiate sub-block.", e); | ||||
} | } | ||||
} | } | ||||
public int getSubBlocksCacheSize() | |||||
{ | |||||
return 8; | |||||
} | |||||
} | } |
@@ -32,7 +32,7 @@ public class ProceduralMapQuadBlock extends AbstractProceduralBlock | |||||
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.getLocalTranslation().x, terrainQuad.getLocalTranslation().z); | ||||
for (int i = 0; i < quadRand.nextInt(10000); i++) { | |||||
for (int i = 0; i < quadRand.nextInt(100); 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) | ||||
@@ -421,15 +421,15 @@ public class FineTerrainGrid extends TerrainQuad { | |||||
int xMax = getSubdivisionsPerSide(); | int xMax = getSubdivisionsPerSide(); | ||||
int yMin = 0; | int yMin = 0; | ||||
int yMax = getSubdivisionsPerSide(); | int yMax = getSubdivisionsPerSide(); | ||||
if (dx == -1) { // camera moved to -X direction | |||||
if (dx < 0) { // camera moved to -X direction | |||||
xMax = getSubdivisionsPerSide() - 1; | xMax = getSubdivisionsPerSide() - 1; | ||||
} else if (dx == 1) { // camera moved to +X direction | |||||
} else if (dx > 0) { // camera moved to +X direction | |||||
xMin = 1; | xMin = 1; | ||||
} | } | ||||
if (dy == -1) { // camera moved to -Y direction | |||||
if (dy < 0) { // camera moved to -Y direction | |||||
yMax = getSubdivisionsPerSide() - 1; | yMax = getSubdivisionsPerSide() - 1; | ||||
} else if (dy == 1) { // camera moved to +Y direction | |||||
} else if (dy > 0) { // camera moved to +Y direction | |||||
yMin = 1; | yMin = 1; | ||||
} | } | ||||
@@ -36,7 +36,7 @@ import roadtrip.view.model.GameWorldState; | |||||
*/ | */ | ||||
public class GameWorldView { | public class GameWorldView { | ||||
public static boolean DEBUG = true; | |||||
public static boolean DEBUG = false;//true; | |||||
private final GameWorldState state; | private final GameWorldState state; | ||||
@@ -184,8 +184,7 @@ public class GameWorldView { | |||||
String quadObjectsNodeKey = getQuadObjectsNodeKey(quad); | String quadObjectsNodeKey = getQuadObjectsNodeKey(quad); | ||||
Node objects = new Node(quadObjectsNodeKey); | Node objects = new Node(quadObjectsNodeKey); | ||||
// TODO: fix | |||||
//populateQuadObjectsNode(quad, objects); | |||||
populateQuadObjectsNode(quad, objects); | |||||
rootNode.attachChild(objects); | rootNode.attachChild(objects); | ||||
} | } | ||||