package org.osm2world.core.target.common.material;
import java.awt.Color;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.configuration.Configuration;
import org.osm2world.core.target.common.TextureData;
import org.osm2world.core.target.common.TextureData.Wrap;
import org.osm2world.core.target.common.material.Material.AmbientOcclusion;
import org.osm2world.core.target.common.material.Material.Interpolation;
import org.osm2world.core.target.common.material.Material.Shadow;
import org.osm2world.core.target.common.material.Material.Transparency;
import org.osm2world.core.util.ConfigUtil;
import org.osm2world.core.world.creation.WorldModule;
/**
* this class defines materials that can be used by all {@link WorldModule}s
*/
public final class Materials {
/** prevents instantiation */
private Materials() {}
/** material for "empty" ground */
public static final ConfMaterial TERRAIN_DEFAULT =
new ConfMaterial(Interpolation.SMOOTH, Color.GREEN);
public static final ConfMaterial WATER =
new ConfMaterial(Interpolation.FLAT, Color.BLUE);
public static final ConfMaterial PURIFIED_WATER =
new ConfMaterial(Interpolation.FLAT, Color.BLUE);
public static final ConfMaterial ASPHALT =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.3f, 0.3f));
public static final ConfMaterial BRICK =
new ConfMaterial(Interpolation.FLAT, new Color(1.0f, 0.5f, 0.25f));
public static final ConfMaterial COBBLESTONE =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.3f, 0.3f));
public static final ConfMaterial CONCRETE =
new ConfMaterial(Interpolation.FLAT, new Color(0.55f, 0.55f, 0.55f));
public static final ConfMaterial EARTH =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0, 0));
public static final ConfMaterial GLASS =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial GRASS =
new ConfMaterial(Interpolation.FLAT, new Color(0.0f, 0.8f, 0.0f));
public static final ConfMaterial GRASS_PAVER =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.5f, 0.3f));
public static final ConfMaterial GRAVEL =
new ConfMaterial(Interpolation.FLAT, new Color(0.4f, 0.4f, 0.4f));
public static final ConfMaterial PAVING_STONE =
new ConfMaterial(Interpolation.FLAT, new Color(0.4f, 0.4f, 0.4f));
public static final ConfMaterial PEBBLESTONE =
new ConfMaterial(Interpolation.FLAT, new Color(0.4f, 0.4f, 0.4f));
public static final ConfMaterial PLASTIC =
new ConfMaterial(Interpolation.FLAT, new Color(0, 0, 0));
public static final ConfMaterial PLASTIC_GREY =
new ConfMaterial(Interpolation.FLAT, new Color(184, 184, 184));
public static final ConfMaterial SAND =
new ConfMaterial(Interpolation.FLAT, new Color(241, 233, 80));
public static final ConfMaterial STEEL =
new ConfMaterial(Interpolation.FLAT, new Color(200, 200, 200));
public static final ConfMaterial WOOD =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.2f, 0.2f));
public static final ConfMaterial WOOD_WALL =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.2f, 0.2f));
public static final ConfMaterial TARTAN =
new ConfMaterial(Interpolation.FLAT, new Color(206, 109, 90));
public static final ConfMaterial ROAD_MARKING =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial ROAD_MARKING_DASHED =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial ROAD_MARKING_ZEBRA =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial ROAD_MARKING_CROSSING =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial ROAD_MARKING_ARROW_THROUGH =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial ROAD_MARKING_ARROW_THROUGH_RIGHT =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial ROAD_MARKING_ARROW_RIGHT =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial ROAD_MARKING_ARROW_RIGHT_LEFT =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial RED_ROAD_MARKING =
new ConfMaterial(Interpolation.FLAT, new Color(0.6f, 0.3f, 0.3f));
public static final ConfMaterial KERB =
new ConfMaterial(Interpolation.FLAT, new Color(0.4f, 0.4f, 0.4f));
public static final ConfMaterial STEPS_DEFAULT =
new ConfMaterial(Interpolation.FLAT, Color.DARK_GRAY);
public static final ConfMaterial HANDRAIL_DEFAULT =
new ConfMaterial(Interpolation.FLAT, Color.LIGHT_GRAY);
public static final ConfMaterial RAIL_DEFAULT =
new ConfMaterial(Interpolation.FLAT, Color.LIGHT_GRAY);
public static final ConfMaterial RAIL_SLEEPER_DEFAULT =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.2f, 0.2f));
public static final ConfMaterial RAIL_BALLAST_DEFAULT =
new ConfMaterial(Interpolation.FLAT, Color.DARK_GRAY);
public static final ConfMaterial BUILDING_DEFAULT =
new ConfMaterial(Interpolation.FLAT, new Color(1f, 0.9f, 0.55f));
public static final ConfMaterial BUILDING_WINDOWS =
new ConfMaterial(Interpolation.FLAT, new Color(1f, 0.9f, 0.55f));
public static final ConfMaterial ROOF_DEFAULT =
new ConfMaterial(Interpolation.FLAT, new Color(0.8f, 0, 0));
public static final ConfMaterial GLASS_ROOF =
new ConfMaterial(Interpolation.FLAT, new Color(0.9f, 0.9f, 0.9f));
public static final ConfMaterial ENTRANCE_DEFAULT =
new ConfMaterial(Interpolation.FLAT, new Color(0.2f, 0, 0));
public static final ConfMaterial GARAGE_DOORS =
new ConfMaterial(Interpolation.FLAT, new Color(1f, 0.9f, 0.55f));
public static final ConfMaterial WALL_DEFAULT =
new ConfMaterial(Interpolation.FLAT, Color.GRAY);
public static final ConfMaterial WALL_GABION =
new ConfMaterial(Interpolation.FLAT, Color.GRAY);
public static final ConfMaterial HEDGE =
new ConfMaterial(Interpolation.FLAT, new Color(0,0.5f,0));
public static final ConfMaterial FENCE_DEFAULT =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.2f, 0.2f));
public static final ConfMaterial SPLIT_RAIL_FENCE =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.2f, 0.2f));
public static final ConfMaterial CHAIN_LINK_FENCE =
new ConfMaterial(Interpolation.FLAT, Color.LIGHT_GRAY);
public static final ConfMaterial CHAIN_LINK_FENCE_POST =
new ConfMaterial(Interpolation.FLAT, new Color(0.1f, 0.5f, 0.1f));
public static final ConfMaterial BRIDGE_DEFAULT =
new ConfMaterial(Interpolation.FLAT, Color.GRAY);
public static final ConfMaterial BRIDGE_PILLAR_DEFAULT =
new ConfMaterial(Interpolation.FLAT, Color.GRAY);
public static final ConfMaterial TUNNEL_DEFAULT =
new ConfMaterial(Interpolation.FLAT, Color.GRAY, 0.2f, 0.5f,
Transparency.FALSE, Collections.<TextureData>emptyList());
public static final ConfMaterial TREE_TRUNK =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.2f, 0.2f));
public static final ConfMaterial TREE_CROWN =
new ConfMaterial(Interpolation.SMOOTH, new Color(0, 0.5f, 0));
public static final ConfMaterial TREE_BILLBOARD_BROAD_LEAVED =
new ConfMaterial(Interpolation.FLAT, new Color(0, 0.5f, 0), 1f, 0f,
Transparency.FALSE, Collections.<TextureData>emptyList());
public static final ConfMaterial TREE_BILLBOARD_BROAD_LEAVED_FRUIT =
new ConfMaterial(Interpolation.FLAT, new Color(0, 0.5f, 0), 1f, 0f,
Transparency.FALSE, Collections.<TextureData>emptyList());
public static final ConfMaterial TREE_BILLBOARD_CONIFEROUS =
new ConfMaterial(Interpolation.FLAT, new Color(0, 0.5f, 0), 1f, 0f,
Transparency.FALSE, Collections.<TextureData>emptyList());
public static final ConfMaterial POWER_TOWER_VERTICAL =
new ConfMaterial(Interpolation.FLAT, new Color(.7f, .7f, .7f), 1f, 0f,
Transparency.BINARY, Collections.<TextureData>emptyList());
public static final ConfMaterial POWER_TOWER_HORIZONTAL =
new ConfMaterial(Interpolation.FLAT, new Color(.7f, .7f, .7f), 1f, 0f,
Transparency.BINARY, Collections.<TextureData>emptyList());
public static final ConfMaterial ADVERTISING_POSTER =
new ConfMaterial(Interpolation.FLAT, new Color(1, 1, 0.8f));
public static final ConfMaterial BUS_STOP_SIGN =
new ConfMaterial(Interpolation.FLAT, new Color(0.98f, 0.90f, 0.05f));
public static final ConfMaterial SIGN_DE_250 =
new ConfMaterial(Interpolation.FLAT, Color.RED);
public static final ConfMaterial SIGN_DE_206 =
new ConfMaterial(Interpolation.FLAT, Color.RED);
public static final ConfMaterial SIGN_DE_625_11 =
new ConfMaterial(Interpolation.FLAT, Color.WHITE);
public static final ConfMaterial SIGN_DE_625_21 =
new ConfMaterial(Interpolation.FLAT, Color.WHITE);
public static final ConfMaterial GRITBIN_DEFAULT =
new ConfMaterial(Interpolation.FLAT, new Color(0.3f, 0.5f, 0.4f));
public static final ConfMaterial POSTBOX_DEUTSCHEPOST =
new ConfMaterial(Interpolation.FLAT, new Color(1f, 0.8f, 0f));
public static final ConfMaterial POSTBOX_ROYALMAIL =
new ConfMaterial(Interpolation.FLAT, new Color(0.8f, 0, 0));
public static final ConfMaterial TELEKOM_MANGENTA =
new ConfMaterial(Interpolation.FLAT, new Color(0.883f, 0f, 0.453f));
public static final ConfMaterial FIREHYDRANT =
new ConfMaterial(Interpolation.FLAT, new Color(0.8f, 0, 0));
public static final ConfMaterial SOLAR_PANEL =
new ConfMaterial(Interpolation.FLAT, Color.BLUE);
public static final ConfMaterial SKYBOX =
new ConfMaterial(Interpolation.FLAT, new Color(0, 0, 1),
1, 0, Transparency.FALSE, null);
private static final Map<String, ConfMaterial> surfaceMaterialMap =
new HashMap<String, ConfMaterial>();
private static final Map<ConfMaterial, String> fieldNameMap =
new HashMap<ConfMaterial, String>();
static {
surfaceMaterialMap.put("asphalt", ASPHALT);
surfaceMaterialMap.put("cobblestone", COBBLESTONE);
surfaceMaterialMap.put("compacted", GRAVEL);
surfaceMaterialMap.put("concrete", CONCRETE);
surfaceMaterialMap.put("grass", GRASS);
surfaceMaterialMap.put("gravel", GRAVEL);
surfaceMaterialMap.put("grass_paver", GRASS_PAVER);
surfaceMaterialMap.put("ground", EARTH);
surfaceMaterialMap.put("paved", ASPHALT);
surfaceMaterialMap.put("paving_stones", PAVING_STONE);
surfaceMaterialMap.put("pebblestone", PEBBLESTONE);
surfaceMaterialMap.put("sand", SAND);
surfaceMaterialMap.put("steel", STEEL);
surfaceMaterialMap.put("tartan", TARTAN);
surfaceMaterialMap.put("unpaved", EARTH);
surfaceMaterialMap.put("wood", WOOD);
try {
for (Field field : Materials.class.getFields()) {
if (field.getType().equals(ConfMaterial.class)) {
fieldNameMap.put(
(ConfMaterial)field.get(null),
field.getName());
}
}
} catch (Exception e) {
throw new Error(e);
}
}
/** returns all materials defined here */
public static final Collection<ConfMaterial> getMaterials() {
return fieldNameMap.keySet();
}
/** returns a material defined here based on its field name */
public static final ConfMaterial getMaterial(String fieldName) {
for (Entry<ConfMaterial, String> entry : fieldNameMap.entrySet()) {
if (entry.getValue().equals(fieldName)) {
return entry.getKey();
}
}
return null;
}
/** returns a material for a surface value; null if none is found */
public static final Material getSurfaceMaterial(String value) {
return getSurfaceMaterial(value, null);
}
/** same as {@link #getSurfaceMaterial(String)}, but with fallback value */
public static final Material getSurfaceMaterial(String value,
Material fallback) {
Material material = surfaceMaterialMap.get(value);
if (material != null) {
return material;
} else {
return fallback;
}
}
/**
* returns a human-readable, unique name for a material defined
* within this class, null for all other materials.
*/
public static final String getUniqueName(Material material) {
return fieldNameMap.get(material);
}
private static final String CONF_KEY_REGEX =
"material_(.+)_(color|specular|shininess|shadow|ssao|transparency|texture\\d*_(?:file|width|height|bumpmap))";
/**
* configures the attributes of the materials within this class
* based on external configuration settings
*/
public static final void configureMaterials(Configuration config) {
// unchecked type parameter necessary due to Apache libs' old interface
@SuppressWarnings("unchecked")
Iterator<String> keyIterator = config.getKeys();
while (keyIterator.hasNext()) {
String key = keyIterator.next();
Matcher matcher = Pattern.compile(CONF_KEY_REGEX).matcher(key);
if (matcher.matches()) {
String materialName = matcher.group(1);
ConfMaterial material = getMaterial(materialName);
if (material != null) {
String attribute = matcher.group(2);
if ("color".equals(attribute)) {
Color color = ConfigUtil.parseColor(
config.getString(key));
if (color != null) {
material.setColor(color);
} else {
System.err.println("incorrect color value: "
+ config.getString(key));
}
} else if ("specular".equals(attribute)) {
float specular = config.getFloat(key);
material.setSpecularFactor(specular);
} else if ("shininess".equals(attribute)) {
int shininess = config.getInt(key);
material.setShininess(shininess);
} else if ("shadow".equals(attribute)) {
String value = config.getString(key).toUpperCase();
Shadow shadow = Shadow.valueOf(value);
if (shadow != null) {
material.setShadow(shadow);
}
} else if ("ssao".equals(attribute)) {
String value = config.getString(key).toUpperCase();
AmbientOcclusion ao = AmbientOcclusion.valueOf(value);
if (ao != null) {
material.setAmbientOcclusion(ao);
}
} else if ("transparency".equals(attribute)) {
String value = config.getString(key).toUpperCase();
Transparency transparency = Transparency.valueOf(value);
if (transparency != null) {
material.setTransparency(transparency);
}
} else if (attribute.startsWith("texture")) {
List<TextureData> textureDataList =
new ArrayList<TextureData>();
for (int i = 0; i < 32; i++) {
String fileKey = "material_" + materialName + "_texture" + i + "_file";
String widthKey = "material_" + materialName + "_texture" + i + "_width";
String heightKey = "material_" + materialName + "_texture" + i + "_height";
String wrapKey = "material_" + materialName + "_texture" + i + "_wrap";
String coordFunctionKey = "material_" + materialName + "_texture" + i + "_coord_function";
String colorableKey = "material_" + materialName + "_texture" + i + "_colorable";
String bumpmapKey = "material_" + materialName + "_texture" + i + "_bumpmap";
if (config.getString(fileKey) == null) break;
File file = new File(config.getString(fileKey));
double width = config.getDouble(widthKey, 1);
double height = config.getDouble(heightKey, 1);
boolean colorable = config.getBoolean(colorableKey, false);
boolean isBumpMap = config.getBoolean(bumpmapKey, false);
String wrapString = config.getString(wrapKey);
Wrap wrap = Wrap.REPEAT;
if ("clamp_to_border".equalsIgnoreCase(wrapString)) {
wrap = Wrap.CLAMP_TO_BORDER;
} else if ("clamp".equalsIgnoreCase(wrapString)) {
wrap = Wrap.CLAMP;
}
String coordFunctionString = config.getString(coordFunctionKey);
TexCoordFunction coordFunction = null;
if (coordFunctionString != null) {
coordFunction = NamedTexCoordFunction.valueOf(
coordFunctionString.toUpperCase());
}
// bumpmaps are only supported in the shader implementation, skip for others
if (!isBumpMap || "shader".equals(config.getString("joglImplementation"))) {
TextureData textureData = new TextureData(
file, width, height, wrap, coordFunction, colorable, isBumpMap);
textureDataList.add(textureData);
}
}
material.setTextureDataList(textureDataList);
} else {
System.err.println("unknown material attribute: "
+ attribute);
}
} else {
System.err.println("unknown material: " + materialName);
}
}
}
}
}