/* * Copyright 2015 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.graph; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import org.terasology.math.Region3i; import org.terasology.math.geom.Vector2i; import org.terasology.polyworld.TriangleLookup; import org.terasology.polyworld.rp.WorldRegion; import org.terasology.world.generation.Border3D; import org.terasology.world.generation.facets.base.BaseFacet2D; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; /** * Provides a collection of {@link Graph}s that * cover the entire facet. */ public class GraphFacetImpl extends BaseFacet2D implements GraphFacet { private final Map<WorldRegion, Graph> graphs = Maps.newLinkedHashMap(); private final List<TriangleLookup> lookups = Lists.newArrayList(); public GraphFacetImpl(Region3i targetRegion, Border3D border) { super(targetRegion, border); } /** * @param graph the graph to add (must overlap the facet area) */ public void add(WorldRegion wr, Graph graph, TriangleLookup lookup) { Preconditions.checkArgument(wr.getArea().equals(graph.getBounds()), "region does not match graph"); Preconditions.checkArgument(graph.getBounds().equals(lookup.getBounds()), "graph does not match triangle lookup"); graphs.put(wr, graph); lookups.add(lookup); } @Override public Graph getWorld(int x, int z) { for (Graph g : graphs.values()) { if (g.getBounds().contains(x, z)) { return g; } } throw new IllegalArgumentException(String.format("no graph data for %d/%d", x, z)); } @Override public Graph getWorld(Vector2i pos) { return getWorld(pos.x, pos.y); } @Override public Triangle getWorldTriangle(int x, int z) { for (TriangleLookup lookup : lookups) { if (lookup.getBounds().contains(x, z)) { return lookup.findTriangleAt(x, z); } } throw new IllegalArgumentException(String.format("no triangle lookup data for %d/%d", x, z)); } @Override public Graph get(int x, int z) { int wx = x - getRelativeRegion().minX() + getWorldRegion().minX(); int wz = z - getRelativeRegion().minY() + getWorldRegion().minY(); return getWorld(wx, wz); } @Override public Graph get(Vector2i pos) { return get(pos.x, pos.y); } @Override public Graph getGraph(WorldRegion wr) { return graphs.get(wr); } @Override public Collection<Graph> getAllGraphs() { return Collections.unmodifiableCollection(graphs.values()); } }