/*
* Copyright 2014 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.polyworld.rivers;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.terasology.polyworld.elevation.ElevationModel;
import org.terasology.polyworld.graph.Corner;
import org.terasology.polyworld.graph.Edge;
import org.terasology.polyworld.graph.Graph;
import org.terasology.polyworld.water.WaterModel;
import com.google.common.collect.Maps;
/**
* TODO Type description
*/
public class DefaultRiverModel implements RiverModel {
private final Map<Edge, Integer> edgeVals = Maps.newHashMap();
private final Map<Corner, Integer> cornerVals = Maps.newHashMap();
public DefaultRiverModel(Graph graph, ElevationModel elevationModel, WaterModel waterModel) {
List<Corner> corners = graph.getCorners();
int count = corners.size() / 50;
Random r = new Random(133353);
for (int i = 0; i < count; i++) {
Corner c = corners.get(r.nextInt(corners.size()));
float elevation = elevationModel.getElevation(c);
if (waterModel.isOcean(c) || elevation < 0.3 || elevation > 0.9) {
continue;
}
// Bias rivers to go west: if (q.downslope.x > q.x) continue;
while (!waterModel.isCoast(c)) {
Corner downslope = elevationModel.getDownslope(c);
if (c == downslope) {
break;
}
Edge edge = lookupEdgeFromCorner(c, downslope);
if (!waterModel.isWater(edge.getCorner0()) || !waterModel.isWater(edge.getCorner1())) {
incrementEdgeVal(edge, 1);
incrementCornerVal(c, 1);
incrementCornerVal(downslope, 1); // TODO: fix float count
}
c = downslope;
}
}
}
public Edge lookupEdgeFromCorner(Corner c1, Corner c2) {
for (Edge e : c1.getEdges()) {
if (e.getCorner0() == c2 || e.getCorner1() == c2) {
return e;
}
}
return null;
}
private void incrementEdgeVal(Edge edge, int inc) {
int newVal = getRiverValue(edge) + inc;
edgeVals.put(edge, Integer.valueOf(newVal));
}
private void incrementCornerVal(Corner corner, int inc) {
int newVal = getRiverValue(corner) + inc;
cornerVals.put(corner, Integer.valueOf(newVal));
}
@Override
public int getRiverValue(Edge edge) {
Integer boxed = edgeVals.get(edge);
return (boxed == null) ? 0 : boxed.intValue();
}
@Override
public int getRiverValue(Corner c) {
Integer boxed = cornerVals.get(c);
return (boxed == null) ? 0 : boxed.intValue();
}
}