// World Political Map - Globe Edition for Unity - Main Script
// Created by Ramiro Oliva (Kronnect)
// Don't modify this script - changes could be lost if you upgrade to a more recent version of WPM
// ***************************************************************************
// This is the public API file - every property or public method belongs here
// ***************************************************************************
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace WPM {
public enum MARKER_TYPE {
CIRCLE = 0,
CIRCLE_PROJECTED = 1,
QUAD = 2
}
public enum GRID_MODE {
OVERLAY = 0,
MASKED = 1
}
public enum CURSOR_STYLE {
Legacy = 0,
LatitudeLongitudeCursor = 1
}
/* Public WPM Class */
public partial class WorldMapGlobe : MonoBehaviour {
[SerializeField]
bool
_showCursor = true;
///
/// Toggle cursor lines visibility.
///
public bool showCursor {
get {
return _showCursor;
}
set {
if (value != _showCursor) {
_showCursor = value;
isDirty = true;
if (cursorLayer != null) {
cursorLayer.SetActive(_showCursor);
}
}
}
}
[SerializeField]
CURSOR_STYLE
_cursorStyle = CURSOR_STYLE.LatitudeLongitudeCursor;
///
/// Gets/sets cursor style.
///
public CURSOR_STYLE cursorStyle {
get {
return _cursorStyle;
}
set {
if (value != _cursorStyle) {
_cursorStyle = value;
isDirty = true;
DrawCursor();
}
}
}
///
/// Cursor lines color.
///
[SerializeField]
Color
_cursorColor = new Color(0.56f, 0.47f, 0.68f);
public Color cursorColor {
get {
if (cursorMat != null) {
return cursorMat.color;
} else {
return _cursorColor;
}
}
set {
if (value != _cursorColor) {
_cursorColor = value;
isDirty = true;
if (cursorMat != null && _cursorColor != cursorMat.color) {
cursorMat.color = _cursorColor;
}
}
}
}
[SerializeField]
bool
_cursorFollowMouse = true;
///
/// Makes the cursor follow the mouse when it's over the World.
///
public bool cursorFollowMouse {
get {
return _cursorFollowMouse;
}
set {
if (value != _cursorFollowMouse) {
_cursorFollowMouse = value;
isDirty = true;
}
}
}
[NonSerialized]
Vector3
_cursorLocation;
public Vector3 cursorLocation {
get {
return _cursorLocation;
}
set {
if (_cursorLocation.x != value.x || _cursorLocation.y != value.y || _cursorLocation.z != value.z) {
_cursorLocation = value;
if (_cursorFollowMouse && cursorLayer != null) {
switch (_cursorStyle) {
case CURSOR_STYLE.Legacy: {
Vector3 wpos = transform.TransformPoint(_cursorLocation);
cursorLayer.transform.LookAt(wpos, transform.up);
}
break;
case CURSOR_STYLE.LatitudeLongitudeCursor: {
// Adjust vertical half cursor
Vector3 wpos = transform.TransformPoint(_cursorLocation);
cursorVertical.transform.LookAt(wpos, transform.up);
// Adjust horizontal half cursor
Vector3 c = _cursorLocation;
c.x *= 2f;
c.z *= 2f;
float s = Mathf.Sqrt(c.x * c.x + c.z * c.z);
c.x = c.z = 0;
cursorHorizontal.transform.localPosition = c;
cursorHorizontal.transform.localScale = new Vector3(s, 1, s);
cursorHorizontal.transform.LookAt(wpos, transform.up);
}
break;
}
}
}
}
}
///
/// If set to false, cursor will be hidden when mouse if not over the globe.
///
[SerializeField]
bool
_cursorAllwaysVisible = true;
public bool cursorAlwaysVisible {
get {
return _cursorAllwaysVisible;
}
set {
if (value != _cursorAllwaysVisible) {
_cursorAllwaysVisible = value;
isDirty = true;
CheckCursorVisibility();
}
}
}
[SerializeField]
bool
_showLatitudeLines = true;
///
/// Toggle latitude lines visibility.
///
public bool showLatitudeLines {
get {
return _showLatitudeLines;
}
set {
if (value != _showLatitudeLines) {
_showLatitudeLines = value;
isDirty = true;
if (latitudeLayer != null) {
latitudeLayer.SetActive(_showLatitudeLines);
} else {
DrawLatitudeLines();
}
}
}
}
[SerializeField]
[Range(5f, 90f)]
int
_latitudeStepping = 15;
///
/// Specify latitude lines separation.
///
public int latitudeStepping {
get {
return _latitudeStepping;
}
set {
if (value != _latitudeStepping) {
_latitudeStepping = value;
isDirty = true;
DrawLatitudeLines();
}
}
}
[SerializeField]
bool
_showLongitudeLines = true;
///
/// Toggle longitude lines visibility.
///
public bool showLongitudeLines {
get {
return _showLongitudeLines;
}
set {
if (value != _showLongitudeLines) {
_showLongitudeLines = value;
isDirty = true;
if (longitudeLayer != null) {
longitudeLayer.SetActive(_showLongitudeLines);
} else {
DrawLongitudeLines();
}
}
}
}
[SerializeField]
[Range(5.0f, 45.0f)]
int
_longitudeStepping = 15;
///
/// Specify longitude lines separation.
///
public int longitudeStepping {
get {
return _longitudeStepping;
}
set {
if (value != _longitudeStepping) {
_longitudeStepping = value;
isDirty = true;
DrawLongitudeLines();
}
}
}
[SerializeField]
Color
_gridColor = new Color(0.16f, 0.33f, 0.498f);
///
/// Color for imaginary lines (longitude and latitude).
///
public Color gridLinesColor {
get {
return _gridColor;
}
set {
if (value != _gridColor) {
_gridColor = value;
isDirty = true;
if (gridMatOverlay != null && _gridColor != gridMatOverlay.color) {
gridMatOverlay.color = _gridColor;
}
if (gridMatMasked != null && _gridColor != gridMatMasked.color) {
gridMatMasked.color = _gridColor;
}
}
}
}
[SerializeField]
GRID_MODE _gridMode = GRID_MODE.OVERLAY;
public GRID_MODE gridMode {
get {
return _gridMode;
}
set {
if (value != _gridMode) {
_gridMode = value;
isDirty = true;
DrawGrid();
}
}
}
#region Public API area
///
/// Adds a text label over the globe.
///
/// The TextMesh component attached to the label gameobject.
/// Sphere location.
/// Text label.
public TextMesh AddText(string name, Vector3 sphereLocation, Color color, float scale = 0.004f, Font font = null, FontStyle fontStyle = FontStyle.Normal) {
if (fontMaterial == null) {
fontMaterial = Instantiate(Resources.Load("Materials/Font"));
}
GameObject go = new GameObject(name);
go.layer = gameObject.layer;
go.transform.SetParent(transform, false);
go.transform.localPosition = sphereLocation; // <-- the location of the city in spherical coordinates
go.transform.localScale = Vector3.one * scale;
go.transform.LookAt(transform.position, transform.up);
TextMesh tm = go.AddComponent();
if (font != null) {
tm.font = font;
}
if (fontStyle != FontStyle.Normal) {
tm.fontStyle = fontStyle;
}
fontMaterial.mainTexture = tm.font.material.mainTexture;
go.GetComponent().sharedMaterial = fontMaterial;
tm.text = name;
tm.alignment = TextAlignment.Center;
tm.anchor = TextAnchor.MiddleCenter;
tm.color = color;
return tm;
}
///
/// Adds a custom marker (gameobject) to the globe on specified location and with custom scale.
///
public void AddMarker(GameObject marker, Vector3 sphereLocation, float markerScale) {
mAddMarker(marker, sphereLocation, markerScale, false, 0f, true);
}
///
/// Adds a custom marker (gameobject) to the globe on specified location and with custom scale.
///
/// If set to true game object will be oriented to position normal facing outside.
/// Makes the marker a little bit off the surface to prevent clipping with other elements like city spots.
/// Takes into account the height of the gameobject mesh and uses the bottom of the object as the reference instead of the middle.
public void AddMarker(GameObject marker, Vector3 sphereLocation, float markerScale, bool isBillboard, float surfaceSeparation = 0f, bool baseLineAtBottom = false, bool preserveOriginalRotation = true) {
mAddMarker(marker, sphereLocation, markerScale, isBillboard, surfaceSeparation, baseLineAtBottom, preserveOriginalRotation);
}
///
/// Adds a custom circle polygon to the globe on specified location and with custom size in km.
///
/// Polygon type.
/// Sphere location.
/// Radius in KM.
/// Ring inner limit (0..1). Pass 0 to draw a full circle.
/// Ring outer limit (0..1). Pass 1 to draw a full circle.
/// Color
public GameObject AddMarker(MARKER_TYPE type, Vector3 sphereLocation, float kmRadius, float ringWidthStart, float ringWidthEnd, Color color) {
return mAddMarkerCircle(type, sphereLocation, kmRadius, ringWidthStart, ringWidthEnd, color);
}
///
/// Adds a quad polygon to the globe on specified location and with custom size.
///
/// Polygon type.
/// Sphere coordinates of the center of the quad.
/// size of quad measured in differences of latitude/longitudes.
/// Color
public GameObject AddMarker(MARKER_TYPE type, Vector3 sphereLocationTopLeft, Vector3 sphereLocationBottomRight, Color fillColor, Color borderColor = default(Color), float borderWidth = 0) {
return mAddMarkerQuad(type, sphereLocationTopLeft, sphereLocationBottomRight, fillColor, borderColor, borderWidth);
}
///
/// Adds a line to the globe with options (returns the line gameobject).
///
/// line color
/// arc elevation relative to the sphere size (0-1 range).
/// drawing speed (0 for instant drawing)
/// duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)
public LineMarkerAnimator AddLine(Vector2 latLonStart, Vector2 latLonEnd, Color color, float arcElevation, float duration, float lineWidth, float fadeOutAfter) {
Vector3 start = Conversion.GetSpherePointFromLatLon(latLonStart.x, latLonStart.y);
Vector3 end = Conversion.GetSpherePointFromLatLon(latLonEnd.x, latLonEnd.y);
return AddLine(start, end, color, arcElevation, duration, lineWidth, fadeOutAfter);
}
///
/// Adds a line to the globe with options (returns the line gameobject).
///
/// line color
/// arc elevation relative to the sphere size (0-1 range).
/// drawing speed (0 for instant drawing)
/// duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)
public LineMarkerAnimator AddLine(float latitudeStart, float longitudeStart, float latitudeEnd, float longitudeEnd, Color color, float arcElevation, float duration, float lineWidth, float fadeOutAfter) {
Vector3 start = Conversion.GetSpherePointFromLatLon(latitudeStart, longitudeStart);
Vector3 end = Conversion.GetSpherePointFromLatLon(latitudeEnd, longitudeEnd);
return AddLine(start, end, color, arcElevation, duration, lineWidth, fadeOutAfter);
}
///
/// Adds a line to the globe with options (returns the line gameobject).
///
/// starting location on the sphere
/// end location on the sphere
/// line color
/// arc elevation relative to the sphere size (0-1 range).
/// drawing speed (0 for instant drawing)
/// duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)
/// uses the same material for the line renderer
public LineMarkerAnimator AddLine(Vector3 spherePosStart, Vector3 spherePosEnd, Color color, float arcElevation, float duration, float lineWidth, float fadeOutAfter, bool reuseMaterial = true) {
CheckMarkersLayer();
GameObject newLine = new GameObject("MarkerLine", typeof(LineMarkerAnimator));
newLine.transform.SetParent(markersLayer.transform, false);
newLine.layer = markersLayer.layer;
LineMarkerAnimator lma = newLine.GetComponent();
lma.start = spherePosStart;
lma.end = spherePosEnd;
lma.color = color;
lma.arcElevation = arcElevation;
lma.duration = duration;
lma.lineWidth = lineWidth;
lma.lineMaterial = GetColoredMarkerLineMaterial(color);
lma.autoFadeAfter = fadeOutAfter;
lma.earthInvertedMode = _earthInvertedMode;
lma.reuseMaterial = reuseMaterial;
return lma;
}
///
/// Adds a line to the globe along a set of points with options (returns the line gameobject).
///
/// sequence of map coordinates
/// line color
public LineMarkerAnimator AddLine(Vector2[] latlon, Color color, float lineWidth) {
CheckMarkersLayer();
GameObject newLine = new GameObject("MarkerLine", typeof(LineMarkerAnimator));
newLine.transform.SetParent(markersLayer.transform, false);
newLine.layer = markersLayer.layer;
LineMarkerAnimator lma = newLine.GetComponent();
lma.SetVertices(latlon);
lma.color = color;
lma.lineWidth = lineWidth;
lma.lineMaterial = markerMatLine;
lma.earthInvertedMode = _earthInvertedMode;
return lma;
}
///
/// Adds a line to the globe along a set of points with options (returns the line gameobject).
///
/// sequence of map coordinates
/// line color
/// arc elevation relative to the sphere size (0-1 range).
/// drawing speed (0 for instant drawing)
/// duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)
/// If the provided material should be instantiated. Set this to true to reuse given material and avoid instantiation.
public LineMarkerAnimator AddLine(Vector2[] latlon, Color color, float lineWidth, float arcElevation, float duration, float fadeOutAfter, bool reuseMaterial) {
CheckMarkersLayer();
GameObject newLine = new GameObject("MarkerLine", typeof(LineMarkerAnimator));
newLine.transform.SetParent(markersLayer.transform, false);
newLine.layer = markersLayer.layer;
LineMarkerAnimator lma = newLine.GetComponent();
lma.SetVertices(latlon);
lma.color = color;
lma.arcElevation = arcElevation;
lma.duration = duration;
lma.lineWidth = lineWidth;
lma.lineMaterial = markerMatLine;
lma.autoFadeAfter = fadeOutAfter;
lma.earthInvertedMode = _earthInvertedMode;
lma.reuseMaterial = reuseMaterial;
return lma;
}
///
/// Adds a polygon with custom color and optional fill color over the globe
///
/// Array of latitude/longitude coordinates
/// The polygon gameobject
public GameObject AddPolygon3D(Vector2[] latlon, Color borderColor, Color fillColor = default(Color)) {
if (latlon == null || latlon.Length < 3) return null;
RefineCoordinates(latlon);
TempCoordinatesToVertices();
GameObject go = null;
// Draw polygon
if (borderColor.a > 0) {
Mesh mesh = new Mesh();
mesh.SetVertices(tempVertices);
mesh.SetIndices(tempIndices.ToArray(), MeshTopology.LineStrip, 0);
go = new GameObject("Polygon3D");
MeshFilter mf = go.AddComponent();
mf.mesh = mesh;
Material mat = Instantiate(borderColor.a < 1f ? frontiersMatThinAlpha : frontiersMatThinOpaque);
mat.color = borderColor;
mat.renderQueue++;
MeshRenderer mr = go.AddComponent();
mr.material = mat;
go.transform.SetParent(transform, false);
}
// Fill poly
if (fillColor.a > 0) {
Material mat = GetProvinceColoredTexturedMaterial(fillColor, null, true);
if (tempRegion == null) {
tempRegion = new Region(null, 0);
}
tempRegion.UpdatePointsAndRect(tempCoords);
GameObject fillGo = GeneratePolygonSurface(tempRegion, mat);
fillGo.hideFlags = 0;
if (go != null) {
fillGo.transform.SetParent(go.transform, false);
} else {
fillGo.transform.SetParent(transform, false);
go = fillGo;
}
fillGo.layer = fillGo.transform.parent.gameObject.layer;
}
return go;
}
///
/// Destroys a marker added to the globe and returned by the function AddMarker
///
public void ClearMarker(GameObject marker) {
if (marker != null) {
Destroy(marker);
}
}
///
/// Deletes a line added to the globe and returned when calling AddLine
///
/// Line.
public void ClearLineMarker(LineMarkerAnimator line) {
if (line != null) {
Destroy(line.gameObject);
}
}
///
/// Deletes all custom markers and lines
///
public void ClearMarkers() {
if (markersLayer != null) {
DestroyImmediate(markersLayer);
}
if (overlayMarkersLayer != null) {
DestroyImmediate(overlayMarkersLayer);
}
requestMapperCamShot = true;
}
///
/// Removes all marker lines.
///
public void ClearLineMarkers() {
if (markersLayer == null)
return;
LineRenderer[] t = markersLayer.transform.GetComponentsInChildren();
for (int k = 0; k < t.Length; k++) {
Destroy(t[k].gameObject);
}
}
#endregion
}
}