DCDC24-EmissionVision/Assets/WorldPoliticalMapGlobeEdition/Scripts/WorldMapGlobeMarkersAndLines.cs
Negin Soltani 37239732ac Initial Push
- Globe Asset
- Spatial Anchors
- Photon Implementation
- Scripts for Globe Control and Initial Country Colorizing
- Script for Reading csv file
2024-05-16 14:41:23 +02:00

606 lines
23 KiB
C#

// 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;
/// <summary>
/// Toggle cursor lines visibility.
/// </summary>
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;
/// <summary>
/// Gets/sets cursor style.
/// </summary>
public CURSOR_STYLE cursorStyle {
get {
return _cursorStyle;
}
set {
if (value != _cursorStyle) {
_cursorStyle = value;
isDirty = true;
DrawCursor();
}
}
}
/// <summary>
/// Cursor lines color.
/// </summary>
[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;
/// <summary>
/// Makes the cursor follow the mouse when it's over the World.
/// </summary>
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;
}
}
}
}
}
/// <summary>
/// If set to false, cursor will be hidden when mouse if not over the globe.
/// </summary>
[SerializeField]
bool
_cursorAllwaysVisible = true;
public bool cursorAlwaysVisible {
get {
return _cursorAllwaysVisible;
}
set {
if (value != _cursorAllwaysVisible) {
_cursorAllwaysVisible = value;
isDirty = true;
CheckCursorVisibility();
}
}
}
[SerializeField]
bool
_showLatitudeLines = true;
/// <summary>
/// Toggle latitude lines visibility.
/// </summary>
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;
/// <summary>
/// Specify latitude lines separation.
/// </summary>
public int latitudeStepping {
get {
return _latitudeStepping;
}
set {
if (value != _latitudeStepping) {
_latitudeStepping = value;
isDirty = true;
DrawLatitudeLines();
}
}
}
[SerializeField]
bool
_showLongitudeLines = true;
/// <summary>
/// Toggle longitude lines visibility.
/// </summary>
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;
/// <summary>
/// Specify longitude lines separation.
/// </summary>
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);
/// <summary>
/// Color for imaginary lines (longitude and latitude).
/// </summary>
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
/// <summary>
/// Adds a text label over the globe.
/// </summary>
/// <returns>The TextMesh component attached to the label gameobject.</returns>
/// <param name="sphereLocation">Sphere location.</param>
/// <param name="name">Text label.</param>
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<Material>(Resources.Load<Material>("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<TextMesh>();
if (font != null) {
tm.font = font;
}
if (fontStyle != FontStyle.Normal) {
tm.fontStyle = fontStyle;
}
fontMaterial.mainTexture = tm.font.material.mainTexture;
go.GetComponent<Renderer>().sharedMaterial = fontMaterial;
tm.text = name;
tm.alignment = TextAlignment.Center;
tm.anchor = TextAnchor.MiddleCenter;
tm.color = color;
return tm;
}
/// <summary>
/// Adds a custom marker (gameobject) to the globe on specified location and with custom scale.
/// </summary>
public void AddMarker(GameObject marker, Vector3 sphereLocation, float markerScale) {
mAddMarker(marker, sphereLocation, markerScale, false, 0f, true);
}
/// <summary>
/// Adds a custom marker (gameobject) to the globe on specified location and with custom scale.
/// </summary>
/// <param name="isBillboard">If set to <c>true</c> game object will be oriented to position normal facing outside.</param>
/// <param name="surfaceSeparation">Makes the marker a little bit off the surface to prevent clipping with other elements like city spots.</param>
/// <param name="baseLineAtBottom">Takes into account the height of the gameobject mesh and uses the bottom of the object as the reference instead of the middle.</param>
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);
}
/// <summary>
/// Adds a custom circle polygon to the globe on specified location and with custom size in km.
/// </summary>
/// <param name="type">Polygon type.</param>
/// <param name="sphereLocation">Sphere location.</param>
/// <param name="kmRadius">Radius in KM.</param>
/// <param name="ringWidthStart">Ring inner limit (0..1). Pass 0 to draw a full circle.</param>
/// <param name="ringWidthEnd">Ring outer limit (0..1). Pass 1 to draw a full circle.</param>
/// <param name="color">Color</param>
public GameObject AddMarker(MARKER_TYPE type, Vector3 sphereLocation, float kmRadius, float ringWidthStart, float ringWidthEnd, Color color) {
return mAddMarkerCircle(type, sphereLocation, kmRadius, ringWidthStart, ringWidthEnd, color);
}
/// <summary>
/// Adds a quad polygon to the globe on specified location and with custom size.
/// </summary>
/// <param name="type">Polygon type.</param>
/// <param name="position">Sphere coordinates of the center of the quad.</param>
/// <param name="size">size of quad measured in differences of latitude/longitudes.</param>
/// <param name="color">Color</param>
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);
}
/// <summary>
/// Adds a line to the globe with options (returns the line gameobject).
/// </summary>
/// <param name="Color">line color</param>
/// <param name="arcElevation">arc elevation relative to the sphere size (0-1 range).</param>
/// <param name="duration">drawing speed (0 for instant drawing)</param>
/// <param name="fadeOutAfter">duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)</param>
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);
}
/// <summary>
/// Adds a line to the globe with options (returns the line gameobject).
/// </summary>
/// <param name="Color">line color</param>
/// <param name="arcElevation">arc elevation relative to the sphere size (0-1 range).</param>
/// <param name="duration">drawing speed (0 for instant drawing)</param>
/// <param name="fadeOutAfter">duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)</param>
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);
}
/// <summary>
/// Adds a line to the globe with options (returns the line gameobject).
/// </summary>
/// <param name="start">starting location on the sphere</param>
/// <param name="end">end location on the sphere</param>
/// <param name="Color">line color</param>
/// <param name="arcElevation">arc elevation relative to the sphere size (0-1 range).</param>
/// <param name="duration">drawing speed (0 for instant drawing)</param>
/// <param name="fadeOutAfter">duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)</param>
/// <param name="reuseMaterial">uses the same material for the line renderer</param>
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<LineMarkerAnimator>();
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;
}
/// <summary>
/// Adds a line to the globe along a set of points with options (returns the line gameobject).
/// </summary>
/// <param name="latlon">sequence of map coordinates</param>
/// <param name="color">line color</param>
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<LineMarkerAnimator>();
lma.SetVertices(latlon);
lma.color = color;
lma.lineWidth = lineWidth;
lma.lineMaterial = markerMatLine;
lma.earthInvertedMode = _earthInvertedMode;
return lma;
}
/// <summary>
/// Adds a line to the globe along a set of points with options (returns the line gameobject).
/// </summary>
/// <param name="latlon">sequence of map coordinates</param>
/// <param name="color">line color</param>
/// <param name="arcElevation">arc elevation relative to the sphere size (0-1 range).</param>
/// <param name="duration">drawing speed (0 for instant drawing)</param>
/// <param name="fadeOutAfter">duration of the line once drawn after which it fades out (set this to 0 to make the line stay forever)</param>
/// <param name="reuseMaterial">If the provided material should be instantiated. Set this to true to reuse given material and avoid instantiation.</param>
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<LineMarkerAnimator>();
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;
}
/// <summary>
/// Adds a polygon with custom color and optional fill color over the globe
/// </summary>
/// <param name="latlon">Array of latitude/longitude coordinates</param>
/// <returns>The polygon gameobject</returns>
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<MeshFilter>();
mf.mesh = mesh;
Material mat = Instantiate(borderColor.a < 1f ? frontiersMatThinAlpha : frontiersMatThinOpaque);
mat.color = borderColor;
mat.renderQueue++;
MeshRenderer mr = go.AddComponent<MeshRenderer>();
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;
}
/// <summary>
/// Destroys a marker added to the globe and returned by the function AddMarker
/// </summary>
public void ClearMarker(GameObject marker) {
if (marker != null) {
Destroy(marker);
}
}
/// <summary>
/// Deletes a line added to the globe and returned when calling AddLine
/// </summary>
/// <param name="line">Line.</param>
public void ClearLineMarker(LineMarkerAnimator line) {
if (line != null) {
Destroy(line.gameObject);
}
}
/// <summary>
/// Deletes all custom markers and lines
/// </summary>
public void ClearMarkers() {
if (markersLayer != null) {
DestroyImmediate(markersLayer);
}
if (overlayMarkersLayer != null) {
DestroyImmediate(overlayMarkersLayer);
}
requestMapperCamShot = true;
}
/// <summary>
/// Removes all marker lines.
/// </summary>
public void ClearLineMarkers() {
if (markersLayer == null)
return;
LineRenderer[] t = markersLayer.transform.GetComponentsInChildren<LineRenderer>();
for (int k = 0; k < t.Length; k++) {
Destroy(t[k].gameObject);
}
}
#endregion
}
}