diff --git a/UnityProjekte/Base Project/Assets/Scripts/NewUIVisual.cs b/UnityProjekte/Base Project/Assets/Scripts/NewUIVisual.cs index f78d6a0..dde0f44 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/NewUIVisual.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/NewUIVisual.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; using TMPro; - +//Controller for the UI public class exampleUIText : MonoBehaviour { public WeatherGetter weatherGetter; @@ -29,16 +29,19 @@ public class exampleUIText : MonoBehaviour // Start is called before the first frame update void Start() { + //empty start disableAllVisualizations(); } // Update is called once per frame void Update() { + //get the weather WeatherGetter.Result? weather = weatherGetter.getWeather(); if (weather is WeatherGetter.Result weatherRes) { if(!weatherRes.isOk){ cityText.text = "Fehler ..."; + //this means the date is outside of the allowed range if (weatherGetter.errorString == "HTTP/1.1 400 Bad Request") { cityText.text = "invalid date"; @@ -47,6 +50,7 @@ void Update() friendlyNameText.text = ""; activateVisualizationObject(null); } + //activate the right visualization else{ activateVisualizationObject(weatherRes.value.weatherType); temperatureText.text = weatherRes.value.temp.ToString("0.0") + " °C"; @@ -62,6 +66,7 @@ void Update() } + //now with english strings string weatherToFriendlyString(WeatherResult.WeatherType weather){ switch(weather){ case WeatherResult.WeatherType.RAIN: @@ -91,6 +96,7 @@ void disableAllVisualizations() thunderstormVisualization.SetActive(false); } + //bad code: emergency fix void activateVisualizationObject(WeatherResult.WeatherType? weather) { if (weather is null) diff --git a/UnityProjekte/Base Project/Assets/Scripts/OWMResult.cs b/UnityProjekte/Base Project/Assets/Scripts/OWMResult.cs index d4976e1..6a1948a 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/OWMResult.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/OWMResult.cs @@ -3,7 +3,7 @@ using UnityEngine; using System; -// Root myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse); +//auto generated, for parsing JSON public class Clouds { public int all ; diff --git a/UnityProjekte/Base Project/Assets/Scripts/OWMWeather.cs b/UnityProjekte/Base Project/Assets/Scripts/OWMWeather.cs index f498162..377767b 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/OWMWeather.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/OWMWeather.cs @@ -6,6 +6,7 @@ public class OWMWeather : WeatherResult { public OWMWeather(double temp, int id, string city):base(temp - 273.15,parseWeatherFromID(id),city) { } + //parse the weather code //Based on: https://openweathermap.org/weather-conditions public static WeatherResult.WeatherType parseWeatherFromID(int id){ int firstDigit = id/100; diff --git a/UnityProjekte/Base Project/Assets/Scripts/OpenMeteoResult.cs b/UnityProjekte/Base Project/Assets/Scripts/OpenMeteoResult.cs index 3b97cea..499a2f2 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/OpenMeteoResult.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/OpenMeteoResult.cs @@ -3,6 +3,7 @@ using UnityEngine; using System; [System.Serializable] +//auto generated, for parsing JSON public class Hourly { public List time; diff --git a/UnityProjekte/Base Project/Assets/Scripts/OpenMeteoWeather.cs b/UnityProjekte/Base Project/Assets/Scripts/OpenMeteoWeather.cs index c2d2413..2de8472 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/OpenMeteoWeather.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/OpenMeteoWeather.cs @@ -1,12 +1,13 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; - +//Open Meteo specific weatherResult public class OpenMeteoWeather : WeatherResult { public OpenMeteoWeather(double temp, int id, string city):base(temp,parseWeatherFromID(id),city) { } + //parse weather ID public static WeatherResult.WeatherType parseWeatherFromID(int id){ switch (id){ case 0: diff --git a/UnityProjekte/Base Project/Assets/Scripts/Rotation/RotateLeft.cs b/UnityProjekte/Base Project/Assets/Scripts/Rotation/RotateLeft.cs index 4aa6409..9aac79e 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/Rotation/RotateLeft.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/Rotation/RotateLeft.cs @@ -7,18 +7,6 @@ public class RotateLeft : MonoBehaviour //GameObject which shold be rotated (Drag&Drop Parameter) public GameObject toRotate; - // Start is called before the first frame update - void Start() - { - - } - - // Update is called once per frame - void Update() - { - - } - /* *Functions which rotates the specified Object while Collider is entered (left) */ diff --git a/UnityProjekte/Base Project/Assets/Scripts/Rotation/RotateRight.cs b/UnityProjekte/Base Project/Assets/Scripts/Rotation/RotateRight.cs index 3fc2e4d..289b338 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/Rotation/RotateRight.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/Rotation/RotateRight.cs @@ -6,19 +6,7 @@ public class RotateRight : MonoBehaviour { public GameObject toRotate; - - // Start is called before the first frame update - void Start() - { - - } - // Update is called once per frame - void Update() - { - - } - /* *Functions which rotates the specified Object while Collider is entered (right) */ diff --git a/UnityProjekte/Base Project/Assets/Scripts/Search.cs b/UnityProjekte/Base Project/Assets/Scripts/Search.cs index 0180bb6..af826f8 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/Search.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/Search.cs @@ -7,22 +7,11 @@ public class Search : MonoBehaviour { public WeatherGetter weatherGetter; - // Start is called before the first frame update - void Start() - { - - - } - - // Update is called once per frame - void Update() - { - - } + //this gets run on "enter" public void submit(){ weatherGetter.updateLocationFromString(GlobalNonNativeKeyboard.instance.keyboard.text); - Debug.Log(GlobalNonNativeKeyboard.instance.keyboard.text); } + //show the keyboard on "click" void OnTriggerEnter(){ GlobalNonNativeKeyboard.instance.ShowKeyboard(); } diff --git a/UnityProjekte/Base Project/Assets/Scripts/TouchPositionFinder.cs b/UnityProjekte/Base Project/Assets/Scripts/TouchPositionFinder.cs index 2394b97..228d52e 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/TouchPositionFinder.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/TouchPositionFinder.cs @@ -2,14 +2,17 @@ public class TouchPositionFinder : MonoBehaviour { + //instead of rotating the globe public float correction = 180.0f; public WeatherGetter weatherGetter; public OSMRequest zoomMap; public float coolDown = 0.0f; private void OnTriggerEnter(Collider other) { - zoomMap.gameObject.SetActive(true); if(coolDown + 1.0f > Time.time) return; + //show the map + zoomMap.gameObject.SetActive(true); + //reset cooldown coolDown = Time.time; Vector3 collisionPoint = other.ClosestPoint(transform.position); Vector3 touchVector = (collisionPoint - gameObject.transform.position).normalized; diff --git a/UnityProjekte/Base Project/Assets/Scripts/WeatherGetter.cs b/UnityProjekte/Base Project/Assets/Scripts/WeatherGetter.cs index c3ff78a..8d88eef 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/WeatherGetter.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/WeatherGetter.cs @@ -23,9 +23,10 @@ public class WeatherGetter : MonoBehaviour public string errorString = ""; void Start() { + //request for now requestTime = DateTime.Now; - requestTime = DateTime.Parse("2024-06-28", null, System.Globalization.DateTimeStyles.RoundtripKind); } + //just a simple Get Request IEnumerator GetRequest(string url) { //using (UnityWebRequest www = UnityWebRequest.Get(baseURL+"&appid=" + apiKey +"&lat=" + lat + "&lon=" + lon )) @@ -71,6 +72,7 @@ IEnumerator GetRequestToOMByCity(string city) } // The using block ensures www.Dispose() is called when this block is exited } + //get Request to OWM by coordinates for geocoding. Continue by a request to Open Meteo IEnumerator GetRequestToOMBCoords(float lat, float lon) { string url = baseURLOWM + apiKeyOWM + "&lat=" + lat.ToString("0.000000", CultureInfo.InvariantCulture) + "&lon=" + lon.ToString("0.000000", CultureInfo.InvariantCulture); @@ -98,11 +100,11 @@ IEnumerator GetRequestToOMBCoords(float lat, float lon) // this will return the current weather if something was requested. Otherwise it will continue return null, unless something arrives public Result? getWeather() { + //not done if (result == null) return null; - //Debug.Log(result.Value.value); + //Error if (!result.Value.isOk) return Result.Error(null); - - + //parse using the right API switch (api){ case API.OPEN_WEATHER_MAP: OWMResult res = JsonUtility.FromJson(result?.value); @@ -137,12 +139,10 @@ public void updateLocation(float lat, float lon) } else { - //requestString = baseURLOPENM + "?latitude=" + lat + "&longitude=" + lon + "&hourly=temperature_2m,weather_code&start_date=" + requestTime.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) + "&end_date=" + requestTime.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); api = API.OPEN_METEO; StartCoroutine(GetRequestToOMBCoords(lat,lon)); } - //Debug.Log(requestString); } //same as updateLocation, but with a string instead of coordinates, expects sanitized input public void updateLocationFromString(string city) @@ -161,13 +161,13 @@ public void updateLocationFromString(string city) } else { - Debug.Log("forecast"); Coroutine rout = StartCoroutine(GetRequestToOMByCity(city)); } } + //Redo the current request public void update(){ if(coords != null) updateLocation(coords.lat,coords.lon); } @@ -176,10 +176,12 @@ public void setRequestTime(DateTime date) requestTime = date; update(); } + //we currently only use those two APIs enum API { OPEN_WEATHER_MAP, OPEN_METEO } + //C# does not have a result type. This why we do this public struct Result{ public static Result Error(T value) => new Result(value,false); public static Result Ok(T value) => new Result(value,true); @@ -193,6 +195,7 @@ public struct Result{ } + //Make coordinates nicer by using a simple object class Coords{ public float lat; public float lon; diff --git a/UnityProjekte/Base Project/Assets/Scripts/WeatherMapGetter.cs b/UnityProjekte/Base Project/Assets/Scripts/WeatherMapGetter.cs index 72c3c10..ca20592 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/WeatherMapGetter.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/WeatherMapGetter.cs @@ -4,6 +4,7 @@ using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; +//this loads the requested tile from OpenStreetMap public class WeatherMapGetter : MonoBehaviour { private Material material; @@ -14,6 +15,7 @@ public class WeatherMapGetter : MonoBehaviour private Texture2DArray textures; void Start() { + //initialize textures and material textures = new Texture2DArray(256, 256, (int)Math.Pow(4, zoomLevel), TextureFormat.ARGB32, true); material = GetComponent().material; for (int x = 0; x < (int)Math.Pow(2, zoomLevel); x++) @@ -23,9 +25,11 @@ void Start() StartCoroutine(GetText(layer, x, y, zoomLevel)); } } + //write attributes to shader material.SetTexture("_TexList", textures); material.SetInteger("_ZoomLevel",zoomLevel); } + //request tile from OSM IEnumerator GetText(string layer, int x, int y, int z) { string url = baseURl + layer + "/"+z+"/"+x+"/"+y+".png?appid=" + apiKey; diff --git a/UnityProjekte/Base Project/Assets/Scripts/WeatherResult.cs b/UnityProjekte/Base Project/Assets/Scripts/WeatherResult.cs index d612509..326b7ba 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/WeatherResult.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/WeatherResult.cs @@ -1,8 +1,8 @@ using System.Collections; using System.Collections.Generic; -//using Unity.VisualScripting; -using UnityEngine; +using UnityEngine; +//abstact class for the weather result public abstract class WeatherResult { //Default Data @@ -15,7 +15,7 @@ public WeatherResult(double temp, WeatherType id, string city) { this.weatherType = id; this.city = city; } - + //could be expanded, for adding new visualizations public enum WeatherType{ SUN,RAIN,SNOW,CLOUDS,THUNDERSTORM } diff --git a/UnityProjekte/Base Project/Assets/Scripts/Zoom/OpenStreetMapTileLayer.cs b/UnityProjekte/Base Project/Assets/Scripts/Zoom/OpenStreetMapTileLayer.cs index 0ba902a..1d5108f 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/Zoom/OpenStreetMapTileLayer.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/Zoom/OpenStreetMapTileLayer.cs @@ -6,7 +6,7 @@ using UnityEngine.XR.Hands; using UnityEngine.XR.Interaction.Toolkit; using UnityEngine.XR; - +//Request to OpenStreetMap public class OSMRequest : MonoBehaviour { public float lat; // Breitengrad @@ -14,8 +14,6 @@ public class OSMRequest : MonoBehaviour public int zoom = 1; private string urlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png"; private float coolDown = 0.0f; - //delta time - private float delta = 0.0f; public WeatherGetter WeatherGetter; private Vector3 firstPos; private Texture2DArray textures; @@ -27,6 +25,8 @@ public class OSMRequest : MonoBehaviour public float swipeVelocity = 0.2f; private TileCache cache; private float zoomOffset = 1.0f; + //tracks the time between entry and exit of finger (for velocity) + private float delta = 0.0f; void Start() { mainMat = gameObject.GetComponent().material; @@ -42,17 +42,22 @@ void Start() private void Update() { + //apply velocity offsetX += velocity.x; offsetY += velocity.y; + //apply zoom, gradually slow down zooom by mean zoomOffset = (zoomOffset + 0.1f)/1.1f; + //clamp offsetX = Mathf.Clamp(offsetX, -1, 1); offsetY = Mathf.Clamp(offsetY, -1, 1); + //send to gpu mainMat.SetFloat("_OffsetX",offsetX); mainMat.SetFloat("_OffsetY",offsetY); mainMat.SetFloat("_ZoomOffset", zoomOffset); + //slow down velocity velocity = velocity * 0.95f; } - + //Load a specific tile into a slot in the texture list IEnumerator LoadTile(int offsetTileIndex) { // Umrechnung der geografischen Koordinaten in Kachelkoordinaten @@ -111,14 +116,14 @@ IEnumerator LoadTile(int offsetTileIndex) } } } - -void GeoToTile(double lat, double lon, int zoom, out int tileX, out int tileY) -{ - double latRad = lat * Math.PI / 180.0; - tileX = (int)((lon + 180.0) / 360.0 * (1 << zoom)); - tileY = (int)((1.0 - Math.Log(Math.Tan(latRad) + 1.0 / Math.Cos(latRad)) / Math.PI) / 2.0 * (1 << zoom)); -} - +//convert coordinates to tile + void GeoToTile(double lat, double lon, int zoom, out int tileX, out int tileY) + { + double latRad = lat * Math.PI / 180.0; + tileX = (int)((lon + 180.0) / 360.0 * (1 << zoom)); + tileY = (int)((1.0 - Math.Log(Math.Tan(latRad) + 1.0 / Math.Cos(latRad)) / Math.PI) / 2.0 * (1 << zoom)); + } + //change new center public void UpdateTile(float newLat, float newLon, int newZoom = 7) { //reset offsets @@ -133,33 +138,25 @@ public void UpdateTile(float newLat, float newLon, int newZoom = 7) } } - + //Set first point private void OnTriggerEnter(Collider other) { + delta = Time.time; Vector3 collisionPoint = transform.InverseTransformPoint(other.transform.position); firstPos = collisionPoint; - delta = Time.time; } - + //react to swipe/poke private void OnTriggerExit(Collider other) { - - Debug.Log(other.name); - if(coolDown + 0.3f > Time.time) return; coolDown = Time.time; - float deltaTime = (Time.time - delta); Vector3 collisionPoint = transform.InverseTransformPoint(other.transform.position); - //other.ClosestPoint(transform.position); - - //swipe detection, a swipe covers a long distance in short time + float deltaTime = (Time.time - delta); + //swipe detection, a swipe covers a long distance Vector3 contactVector = firstPos - collisionPoint; - - //check if hand-tracking is enabled: - //if (InputDeviceCharacteristics.) { - //} + //the swipe sensitivity seems to be dependent on the device used. Why? I don't know float swipeSens = 0; - //kid named finger + //the collider was a finger if(other.name.Equals("Capsule Collider Proximal")) { swipeSens = 1f; @@ -170,35 +167,39 @@ private void OnTriggerExit(Collider other) { swipeSens = 2f; } + //poke if (contactVector.magnitude <= swipeSens) { + //get the world coordinates of the four corner points GeoToTile(lat, lon, zoom, out int x, out int y); - float lonBottomLeft = tileToLon(x, zoom); float latBottomLeft = tileToLat(y + 1, zoom); float lonTopRight = tileToLon(x + 1, zoom); float latTopRight = tileToLat(y, zoom); + //get touch as vector Vector3 corner = new Vector3(-5f, -0f, -5f); //account for rotation gameObject.transform.position - Vector3 touch = new Vector3(10,0,10) - (collisionPoint - corner); float latStep = latTopRight - latBottomLeft; float lonStep = lonTopRight - lonBottomLeft; + //linear interpolation between the corners, dependent on the touch vector float resLat = ((touch.z / 10f) + offsetY) * latStep + latBottomLeft; float resLon = ((touch.x / 10f) + offsetX) * lonStep + lonBottomLeft; + //send to weatherGetter WeatherGetter.updateLocation(resLat, resLon); //hide on click gameObject.SetActive(false); } + //swipe else { - Debug.Log(contactVector.magnitude); velocity = new Vector2(contactVector.x, contactVector.z) * -swipeVelocity/deltaTime; } } - + //zoom in or out public void changeZoom(int step) { if (step == 1) @@ -206,7 +207,7 @@ public void changeZoom(int step) zoomOffset = 2f; } else zoomOffset = 0.5f; - //recenter + //recenter, same as in OnTriggerExit GeoToTile(lat, lon, zoom, out int x, out int y); float lonBottomLeft = tileToLon(x, zoom); float latBottomLeft = tileToLat(y + 1, zoom); diff --git a/UnityProjekte/Base Project/Assets/Scripts/Zoom/TileCache.cs b/UnityProjekte/Base Project/Assets/Scripts/Zoom/TileCache.cs index fec26f2..079f860 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/Zoom/TileCache.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/Zoom/TileCache.cs @@ -9,6 +9,7 @@ public class TileCache public TileCache() { + //create an array with lists table = new List[TABLE_SIZE]; for (int i = 0; i < TABLE_SIZE; i++) { @@ -23,11 +24,9 @@ public Color[] Get(int x, int y, int z) { if (entry.x == x && entry.y == y && entry.z == z) { - //Debug.Log("hit"); return entry.value; } } - //Debug.Log("miss"); return null; } //add something to the cache @@ -36,7 +35,7 @@ public void Insert(int x, int y, int z, Color[] tile) TileCacheEntry entry = new TileCacheEntry(x, y, z, tile); table[entry.hashCode(TABLE_SIZE)].Add(entry); } - + //naive hash function private int hashCode(int x,int y, int z) { int prime1 = 73856093; diff --git a/UnityProjekte/Base Project/Assets/Scripts/Zoom/ZoomInteractionController.cs b/UnityProjekte/Base Project/Assets/Scripts/Zoom/ZoomInteractionController.cs index 4365a14..0f27e1a 100644 --- a/UnityProjekte/Base Project/Assets/Scripts/Zoom/ZoomInteractionController.cs +++ b/UnityProjekte/Base Project/Assets/Scripts/Zoom/ZoomInteractionController.cs @@ -9,11 +9,6 @@ public class ZoomInteractionController : MonoBehaviour public int zoomEffectVal; private float coolDown = 0.0f; - // Start is called before the first frame update - void Start() - { - - } private void OnTriggerEnter(Collider other) { @@ -22,7 +17,6 @@ private void OnTriggerEnter(Collider other) //does not look good anymore if (map.zoom <= 3 || map.zoom >= 18) return; map.changeZoom(zoomEffectVal); - //map.UpdateTile(map.lat,map.lon, map.zoom+zoomEffectMagnitude); } }