![Negin Soltani](/assets/img/avatar_default.png)
- Globe Asset - Spatial Anchors - Photon Implementation - Scripts for Globe Control and Initial Country Colorizing - Script for Reading csv file
178 lines
5.3 KiB
C#
178 lines
5.3 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
namespace WPM {
|
|
|
|
public class DemoVirus : MonoBehaviour {
|
|
|
|
const int MAX_BOUNCES = 8;
|
|
|
|
public Material circleMat, combineMat;
|
|
public Texture2D earthMask;
|
|
|
|
WorldMapGlobe map;
|
|
GUIStyle buttonStyle;
|
|
RenderTexture[] rtEarth, rtVirusMap, rtCombined;
|
|
EarthTexture[] earthTextures;
|
|
Material earthMat;
|
|
int bounces;
|
|
|
|
void Start () {
|
|
buttonStyle = new GUIStyle ();
|
|
buttonStyle.alignment = TextAnchor.MiddleLeft;
|
|
buttonStyle.normal.background = Texture2D.whiteTexture;
|
|
buttonStyle.normal.textColor = Color.white;
|
|
|
|
// setup GUI resizer - only for the demo
|
|
GUIResizer.Init (800, 500);
|
|
|
|
// Get map instance to Globe API methods
|
|
map = WorldMapGlobe.instance;
|
|
earthMat = map.earthMaterial;
|
|
|
|
// Gets a copy of current Earth texture and make it available as render texture for faster blending
|
|
earthTextures = map.earthTextures;
|
|
|
|
int numTextures = earthTextures.Length;
|
|
int width = earthTextures [0].texture.width;
|
|
int height = earthTextures [0].texture.height;
|
|
rtEarth = new RenderTexture[numTextures];
|
|
rtVirusMap = new RenderTexture[numTextures];
|
|
rtCombined = new RenderTexture[numTextures];
|
|
for (int k = 0; k < numTextures; k++) {
|
|
rtEarth [k] = new RenderTexture (width, height, 0);
|
|
Graphics.Blit (earthTextures [k].texture, rtEarth [k]);
|
|
rtVirusMap [k] = new RenderTexture (width, height, 0);
|
|
rtCombined [k] = new RenderTexture (width, height, 0);
|
|
}
|
|
|
|
circleMat.SetTexture ("_MaskTex", earthMask); // to avoid painting over Sea
|
|
|
|
map.OnClick += (Vector3 sphereLocation, int mouseButtonIndex) => {
|
|
StartCoroutine (SpreadAtLatLon (Conversion.GetLatLonFromSpherePoint (sphereLocation), 0.005f, 1f));
|
|
};
|
|
|
|
StartPlague ();
|
|
}
|
|
|
|
void OnGUI () {
|
|
GUIResizer.AutoResize ();
|
|
GUI.backgroundColor = new Color (0.1f, 0.1f, 0.3f, 0.5f);
|
|
if (GUI.Button (new Rect (10, 10, 160, 30), " Start Plague Again", buttonStyle)) {
|
|
StartPlague ();
|
|
}
|
|
GUI.Label (new Rect (20, 50, 300, 30), "Click to spread plague at cursor position");
|
|
}
|
|
|
|
void StartPlague () {
|
|
for (int k = 0; k < rtVirusMap.Length; k++) {
|
|
rtVirusMap [k].Clear (false, true, Misc.ColorTransparent);
|
|
}
|
|
|
|
// Get a random city
|
|
int cityRandom = Random.Range (0, map.cities.Count);
|
|
Vector2 pointZero = map.cities [cityRandom].latlon;
|
|
Spread (cityRandom);
|
|
}
|
|
|
|
|
|
|
|
void Spread (int cityIndex) {
|
|
City city = map.cities [cityIndex];
|
|
Vector2 latlon = city.latlon;
|
|
float radius = 0.002f;
|
|
switch (city.cityClass) {
|
|
case CITY_CLASS.REGION_CAPITAL:
|
|
radius += 0.004f;
|
|
break;
|
|
case CITY_CLASS.COUNTRY_CAPITAL:
|
|
radius += 0.007f;
|
|
break;
|
|
}
|
|
radius += Random.value * 0.005f;
|
|
|
|
StartCoroutine (SpreadAtLatLon (latlon, radius, 4f));
|
|
}
|
|
|
|
IEnumerator SpreadAtLatLon (Vector2 latlon, float radius, float duration) {
|
|
|
|
WaitForEndOfFrame w = new WaitForEndOfFrame ();
|
|
Vector2 uv = Conversion.GetUVFromLatLon (latlon.x, latlon.y);
|
|
float startTime = Time.time;
|
|
float t = 0;
|
|
Material circleInstancedMat = Instantiate (circleMat); // copy of material to allow different _UVRect per circle
|
|
|
|
do {
|
|
t = (Time.time - startTime) / duration;
|
|
if (t > 1f)
|
|
t = 1f;
|
|
for (int k = 0; k < earthTextures.Length; k++) {
|
|
Vector4 uvRect = earthTextures [k].uvRect;
|
|
if (uv.x + radius >= uvRect.x && uv.x - radius <= uvRect.x + uvRect.z && uv.y + radius >= uvRect.y && uv.y - radius <= uvRect.y + uvRect.w) {
|
|
circleInstancedMat.SetVector ("_UVRect", uvRect);
|
|
rtVirusMap [k].Circle (uv, t * radius, circleInstancedMat);
|
|
}
|
|
}
|
|
yield return w;
|
|
|
|
if (Random.value > 0.97f && bounces < MAX_BOUNCES) {
|
|
Bounce (latlon);
|
|
}
|
|
} while(t < 1f);
|
|
Bounce (latlon);
|
|
bounces--;
|
|
}
|
|
|
|
void Bounce (Vector2 latlonStart) {
|
|
// Spread to another near city
|
|
int anotherCity = 0;
|
|
float minDist = float.MaxValue;
|
|
for (int k = 0; k < 25; k++) {
|
|
int c = Random.Range (0, map.cities.Count);
|
|
float dist = map.calc.Distance (latlonStart, map.cities [c].latlon);
|
|
if (dist < minDist) {
|
|
anotherCity = c;
|
|
minDist = dist;
|
|
}
|
|
}
|
|
Vector2 dest = map.cities [anotherCity].latlon;
|
|
LineMarkerAnimator line = map.AddLine (latlonStart, dest, Color.yellow, 0.1f, 2f, 0.05f, 0.1f);
|
|
line.OnLineDrawingEnd += (LineMarkerAnimator lma) => {
|
|
Spread (anotherCity);
|
|
};
|
|
bounces++;
|
|
|
|
}
|
|
|
|
|
|
void Update () {
|
|
// Combine virus map with Earth texture
|
|
for (int k = 0; k < rtVirusMap.Length; k++) {
|
|
combineMat.SetTexture ("_SecondTex", rtVirusMap [k]);
|
|
Graphics.Blit (rtEarth [k], rtCombined [k], combineMat);
|
|
earthMat.SetTexture (earthTextures [k].shaderTextureName, rtCombined [k]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static class RenderTextureExtensions {
|
|
|
|
public static void Clear (this RenderTexture rt, bool clearDepth, bool clearColor, Color backgroundColor) {
|
|
RenderTexture old = RenderTexture.active;
|
|
RenderTexture.active = rt;
|
|
GL.Clear (clearDepth, clearColor, backgroundColor);
|
|
RenderTexture.active = old;
|
|
}
|
|
|
|
public static void Circle (this RenderTexture rt, Vector2 uv, float radius, Material mat) {
|
|
RenderTexture old = RenderTexture.active;
|
|
RenderTexture.active = rt;
|
|
mat.SetVector ("_CenterAndRadius", new Vector3 (uv.x, uv.y, radius * radius));
|
|
Graphics.Blit (null, rt, mat);
|
|
RenderTexture.active = old;
|
|
}
|
|
}
|
|
}
|