Package org.osm2world.core.world.modules

Source Code of org.osm2world.core.world.modules.BridgeModule

package org.osm2world.core.world.modules;


import static org.osm2world.core.math.GeometryUtil.*;
import static org.osm2world.core.world.modules.common.WorldModuleGeometryUtil.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.openstreetmap.josm.plugins.graphview.core.data.TagGroup;
import org.osm2world.core.map_data.data.MapWaySegment;
import org.osm2world.core.map_data.data.overlaps.MapIntersectionWW;
import org.osm2world.core.map_elevation.data.EleConnector;
import org.osm2world.core.map_elevation.data.GroundState;
import org.osm2world.core.math.VectorXYZ;
import org.osm2world.core.math.VectorXZ;
import org.osm2world.core.target.RenderableToAllTargets;
import org.osm2world.core.target.Target;
import org.osm2world.core.target.common.material.Materials;
import org.osm2world.core.world.data.WaySegmentWorldObject;
import org.osm2world.core.world.data.WorldObject;
import org.osm2world.core.world.modules.WaterModule.Water;
import org.osm2world.core.world.modules.common.AbstractModule;
import org.osm2world.core.world.modules.common.BridgeOrTunnel;
import org.osm2world.core.world.network.AbstractNetworkWaySegmentWorldObject;

/**
* adds bridges to the world.
*
* Needs to be applied <em>after</em> all the modules that generate
* whatever runs over the bridge.
*/
public class BridgeModule extends AbstractModule {

  public static final boolean isBridge(TagGroup tags) {
    return tags.containsKey("bridge")
      && !"no".equals(tags.getValue("bridge"));
  }
 
  public static final boolean isBridge(MapWaySegment segment) {
    return isBridge(segment.getTags());
  }
 
  @Override
  protected void applyToWaySegment(MapWaySegment segment) {
   
    WaySegmentWorldObject primaryRepresentation =
      segment.getPrimaryRepresentation();
   
    if (primaryRepresentation instanceof AbstractNetworkWaySegmentWorldObject
        && isBridge(segment)) {
     
      segment.addRepresentation(new Bridge(segment,
          (AbstractNetworkWaySegmentWorldObject) primaryRepresentation));
     
    }
   
  }
 
  public static final double BRIDGE_UNDERSIDE_HEIGHT = 0.2f;
   
  private static class Bridge extends BridgeOrTunnel
      implements RenderableToAllTargets {
   
    public Bridge(MapWaySegment segment,
        AbstractNetworkWaySegmentWorldObject primaryWO) {
      super(segment, primaryWO);
    }

    @Override
    public GroundState getGroundState() {
      return GroundState.ABOVE;
    }
   
    @Override
    public Iterable<EleConnector> getEleConnectors() {
      // TODO EleConnectors for pillars
      return super.getEleConnectors();
    }
   
    @Override
    public void renderTo(Target<?> target) {

      drawBridgeUnderside(target);
           
      drawBridgePillars(target);
     
    }

    private void drawBridgeUnderside(Target<?> target) {
     
      List<VectorXYZ> leftOutline = primaryRep.getOutline(false);
      List<VectorXYZ> rightOutline = primaryRep.getOutline(true);
     
      List<VectorXYZ> belowLeftOutline = sequenceAbove(leftOutline, -BRIDGE_UNDERSIDE_HEIGHT);
      List<VectorXYZ> belowRightOutline = sequenceAbove(rightOutline, -BRIDGE_UNDERSIDE_HEIGHT);
     
      List<VectorXYZ> strip1 = createTriangleStripBetween(
          belowLeftOutline, leftOutline);
      List<VectorXYZ> strip2 = createTriangleStripBetween(
          belowRightOutline, belowLeftOutline);
      List<VectorXYZ> strip3 = createTriangleStripBetween(
          rightOutline, belowRightOutline);
     
      target.drawTriangleStrip(Materials.BRIDGE_DEFAULT, strip1, null);
      target.drawTriangleStrip(Materials.BRIDGE_DEFAULT, strip2, null);
      target.drawTriangleStrip(Materials.BRIDGE_DEFAULT, strip3, null);
     
    }

    private void drawBridgePillars(Target<?> target) {
     
      List<VectorXZ> pillarPositions = equallyDistributePointsAlong(
          2f, false,
          primaryRep.getStartPosition(),
          primaryRep.getEndPosition());
     
      //make sure that the pillars doesn't pierce anything on the ground
     
      Collection<WorldObject> avoidedObjects = new ArrayList<WorldObject>();
     
      for (MapIntersectionWW i : segment.getIntersectionsWW()) {
        for (WorldObject otherRep : i.getOther(segment).getRepresentations()) {
         
          if (otherRep.getGroundState() == GroundState.ON
              && !(otherRep instanceof Water) //TODO: choose better criterion!
          ) {
            avoidedObjects.add(otherRep);
          }
       
        }
      }
     
      filterWorldObjectCollisions(pillarPositions, avoidedObjects);
     
      //draw the pillars
     
      for (VectorXZ pos : pillarPositions) {
        drawBridgePillarAt(target, pos);
      }
     
    }

    private void drawBridgePillarAt(Target<?> target, VectorXZ pos) {
   
      /* determine the bridge elevation at that point */
     
      VectorXYZ top = null;
     
      List<VectorXYZ> vs = primaryRep.getCenterline();
     
      for (int i = 0; i + 1 < vs.size(); i++) {
       
        if (isBetween(pos, vs.get(i).xz(), vs.get(i+1).xz())) {
          top = interpolateElevation(pos, vs.get(i), vs.get(i+1));
        }
       
      }

      /* draw the pillar */
     
      // TODO: start pillar at ground instead of just 100 meters below the bridge
      target.drawColumn(Materials.BRIDGE_PILLAR_DEFAULT, null,
          top.addY(-100),
          100,
          0.2, 0.2, false, false);

    }
   
  }
 
}
TOP

Related Classes of org.osm2world.core.world.modules.BridgeModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
ddress">java.net.InetSocketAddress
  • java.io.OutputStream
  • TOP
    Copyright © 2018 www.massapi.com. All rights reserved.
    All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.