mirror of
https://github.com/RaindropViewer/RaindropViewer.git
synced 2026-07-27 22:11:39 +00:00
working on making the map viewer that can support pan and zoom
This commit is contained in:
@@ -12,7 +12,8 @@
|
||||
"GUID:247a163e3cc6efb42bd22b9023b87ff3",
|
||||
"GUID:0c752da273b17c547ae705acf0f2adf2",
|
||||
"GUID:0d8beb7f090555447a6cf5ce9e54dbb4",
|
||||
"GUID:11f3455556175aa41b2b4d4f2ec8b146"
|
||||
"GUID:11f3455556175aa41b2b4d4f2ec8b146",
|
||||
"GUID:75469ad4d38634e559750d17036d5f7c"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using ServiceLocator;
|
||||
using Raindrop.Map.Model;
|
||||
|
||||
namespace Raindrop
|
||||
{
|
||||
@@ -37,6 +38,13 @@ namespace Raindrop
|
||||
//return;
|
||||
}
|
||||
|
||||
if (! ServiceLocator.ServiceLocator.Instance.IsRegistered<MapBackend>())
|
||||
{
|
||||
Debug.LogWarning("UIBootstrapper creating and registering MapBackend.MapFetcher!");
|
||||
ServiceLocator.ServiceLocator.Instance.Register<MapBackend>(new MapBackend());
|
||||
//return;
|
||||
}
|
||||
|
||||
var cm = GetComponentInChildren<CanvasManager>();
|
||||
var mm = GetComponentInChildren<ModalManager>();
|
||||
|
||||
|
||||
@@ -1,282 +0,0 @@
|
||||
using OpenMetaverse;
|
||||
using Raindrop.Network;
|
||||
using Raindrop.UI;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Raindrop.Map
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains logic to fetch and decode the map textures.
|
||||
/// </summary>
|
||||
|
||||
public class MapLogic
|
||||
{
|
||||
#region range logic
|
||||
|
||||
// ---------@ max
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
//min @---------
|
||||
|
||||
// range - bottom left corner
|
||||
internal static OpenMetaverse.Vector2 getMinVec2(OpenMetaverse.Vector2 range, OpenMetaverse.Vector2 focalPoint)
|
||||
{
|
||||
return focalPoint - new OpenMetaverse.Vector2(range.X / 2 , range.Y / 2);
|
||||
}
|
||||
|
||||
// range - top right corner
|
||||
|
||||
internal static OpenMetaverse.Vector2 getMaxVec2(OpenMetaverse.Vector2 range, OpenMetaverse.Vector2 focalPoint)
|
||||
{
|
||||
return focalPoint + new OpenMetaverse.Vector2(range.X / 2 , range.Y / 2);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
//backend image fetch logic
|
||||
|
||||
|
||||
// map fetching class.
|
||||
// contains a dict for tracking the tile maps.
|
||||
// contains the reusable pool to discard and recycle tile maps.
|
||||
public class MapFetcher
|
||||
{
|
||||
MapDataManager mapDataMgr;
|
||||
List<ulong> tileRequests = new List<ulong>(); // a list of pending fetch requests. the ulongs are the x and y world coordinates (gridX * 256), packed.
|
||||
uint regionSize = 256;
|
||||
private ParallelDownloader downloader;
|
||||
int poolSize = 10;
|
||||
|
||||
UnityMainThreadDispatcher mainThreadInstance;
|
||||
|
||||
public MapFetcher()
|
||||
{
|
||||
mapDataMgr = new MapDataManager(10);
|
||||
|
||||
downloader = new ParallelDownloader();
|
||||
|
||||
mainThreadInstance = UnityMainThreadDispatcher.Instance();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API to Get the map tile at specific region handle and zoom level. Only zoom level 1 is supported.
|
||||
/// </summary>
|
||||
/// <param name="handle"></param>
|
||||
/// <param name="zoom"></param>
|
||||
/// <returns></returns>
|
||||
public MapTile GetMapTile(ulong handle, int zoom)
|
||||
{
|
||||
MapTile res = null;
|
||||
|
||||
//try
|
||||
//{
|
||||
res = mapDataMgr.tryGetTile(handle);
|
||||
//}
|
||||
//catch (Exception)
|
||||
//{
|
||||
uint x, y;
|
||||
Utils.LongToUInts(handle, out x, out y);
|
||||
Debug.LogError("no tile found at " + x + " " + y);
|
||||
//}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//get region tile using SL map API -- JPEG images.
|
||||
// obtains the image from URL, decodes it in main thread, the stores data in the appropriate maptile.
|
||||
public MapTile GetRegionTileExternal(ulong handle, int zoom)
|
||||
{
|
||||
if ( (zoom > 4) || (zoom < 1) )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (GetMapTile(handle, 1) != null)
|
||||
{
|
||||
return GetMapTile(handle, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (tileRequests)
|
||||
{
|
||||
if (tileRequests.Contains(handle)) return null;
|
||||
tileRequests.Add(handle);
|
||||
}
|
||||
|
||||
uint regX, regY;
|
||||
Utils.LongToUInts(handle, out regX, out regY);
|
||||
regX /= regionSize;
|
||||
regY /= regionSize;
|
||||
//int zoom = 1;
|
||||
|
||||
downloader.QueueDownlad(
|
||||
new Uri(string.Format("http://map.secondlife.com/map-{0}-{1}-{2}-objects.jpg", zoom, regX, regY)),
|
||||
20 * 1000,
|
||||
null,
|
||||
null,
|
||||
(request, response, responseData, error) =>
|
||||
{
|
||||
if (error == null && responseData != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Log("fetching the texture was successful!");
|
||||
|
||||
//lock (mapData.sceneTiles)
|
||||
//{
|
||||
Debug.Log("1");
|
||||
//decode http response data into texture2d
|
||||
//MapTile tex = mapData.getTile();
|
||||
MapTile tex = mapDataMgr.setEmptyTile(handle); //Tile is a empty tile right now -- we write to it soon.
|
||||
|
||||
Debug.Log("2");
|
||||
//run jpeg decoding on the main thread, for now.
|
||||
mainThreadInstance.Enqueue(DecodeDataToTexAsync(tex, responseData));
|
||||
|
||||
Debug.Log("3");
|
||||
//set the tile into tile manager
|
||||
mapDataMgr.setTile( handle,tex);
|
||||
Debug.Log("4");
|
||||
//}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
//lock (mapData.sceneTiles)
|
||||
//{
|
||||
// mapData.sceneTiles[handle] = mapData.acquireTile(); //wtf!
|
||||
//}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator DecodeDataToTexAsync(MapTile tex, byte[] responseData)
|
||||
{
|
||||
try
|
||||
{
|
||||
Texture2D _tex = tex.getTex();
|
||||
bool success = _tex.LoadImage(responseData);
|
||||
|
||||
}
|
||||
catch (Exception w)
|
||||
{
|
||||
Debug.Log("decode the texture failed : " + w.Message);
|
||||
}
|
||||
Debug.Log("completed mainthread async texture Decode.");
|
||||
|
||||
yield return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// get image from cache or asset manager. returns tex2D.
|
||||
// should only be used for the minimap. Use http map API fetch for normal map.
|
||||
//Texture2D DownloadRegionTile(ulong handle, UUID imageID, GridClient Client)
|
||||
//{
|
||||
// //if (mapData.regionTiles.ContainsKey(handle)) return;
|
||||
|
||||
// //lock (tileRequests)
|
||||
// // if (!tileRequests.Contains(handle))
|
||||
// // tileRequests.Add(handle);
|
||||
|
||||
|
||||
// Uri url = Client.Network.CurrentSim.Caps.GetTextureCapURI();
|
||||
// if (url != null)
|
||||
// {
|
||||
// if (Client.Assets.Cache.HasAsset(imageID))
|
||||
// {
|
||||
// Texture2D img;
|
||||
// OpenMetaverse.Imaging.ManagedImage mi;
|
||||
// if (OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(Client.Assets.Cache.GetCachedAssetBytes(imageID), out mi, out img))
|
||||
// {
|
||||
// return img;
|
||||
// //mapData.regionTiles[handle] = img;
|
||||
// }
|
||||
// lock (tileRequests)
|
||||
// if (tileRequests.Contains(handle))
|
||||
// tileRequests.Remove(handle);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// downloader.QueueDownlad(
|
||||
// new Uri($"{url}/?texture_id={imageID}"),
|
||||
// 30 * 1000,
|
||||
// "image/x-j2c",
|
||||
// null,
|
||||
// (request, response, responseData, error) =>
|
||||
// {
|
||||
// if (error == null && responseData != null)
|
||||
// {
|
||||
// Image img;
|
||||
// OpenMetaverse.Imaging.ManagedImage mi;
|
||||
// if (OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(responseData, out mi, out img))
|
||||
// {
|
||||
// mapData.regionTiles[handle] = img;
|
||||
// Client.Assets.Cache.SaveAssetToCache(imageID, responseData);
|
||||
// }
|
||||
// }
|
||||
|
||||
// lock (tileRequests)
|
||||
// {
|
||||
// if (tileRequests.Contains(handle))
|
||||
// {
|
||||
// tileRequests.Remove(handle);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Client.Assets.RequestImage(imageID, (state, assetTexture) =>
|
||||
// {
|
||||
// switch (state)
|
||||
// {
|
||||
// case TextureRequestState.Pending:
|
||||
// case TextureRequestState.Progress:
|
||||
// case TextureRequestState.Started:
|
||||
// return;
|
||||
|
||||
// case TextureRequestState.Finished:
|
||||
// if (assetTexture?.AssetData != null)
|
||||
// {
|
||||
// Image img;
|
||||
// OpenMetaverse.Imaging.ManagedImage mi;
|
||||
// if (OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(assetTexture.AssetData, out mi, out img))
|
||||
// {
|
||||
// mapData.regionTiles[handle] = img;
|
||||
// }
|
||||
// }
|
||||
// lock (tileRequests)
|
||||
// if (tileRequests.Contains(handle))
|
||||
// tileRequests.Remove(handle);
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// lock (tileRequests)
|
||||
// if (tileRequests.Contains(handle))
|
||||
// tileRequests.Remove(handle);
|
||||
// break;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Raindrop;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace Raindrop.Presenters
|
||||
{
|
||||
//an instance of a map 'look at' ; the focal point of camera.
|
||||
public class MapMover : MonoBehaviour
|
||||
{
|
||||
//grid coordinates * 256
|
||||
[SerializeField]
|
||||
public uint lookAt_x = 1000 * 256;
|
||||
[SerializeField]
|
||||
public uint lookAt_y = 1000 * 256;
|
||||
|
||||
/// <summary>
|
||||
/// get lookat of the camera in ( gridCoord * 256 ) units
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
public ulong GetLookAt()
|
||||
{
|
||||
return Utils.UIntsToLong(lookAt_x, lookAt_y);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,23 +6,22 @@ using System.Threading.Tasks;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using Raindrop.Map;
|
||||
using Raindrop.UI.Views;
|
||||
|
||||
namespace Raindrop.UI
|
||||
{
|
||||
// manages the pool of map textures and gameobjects.
|
||||
// map pool.
|
||||
// map maker
|
||||
/// <summary>
|
||||
/// manages the pool of map textures and gameobjects.
|
||||
/// map pool.
|
||||
/// map maker
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
class MapPoolPresenter : MonoBehaviour
|
||||
class MapPoolPresenter
|
||||
{
|
||||
private MapSceneView mapSceneView;
|
||||
|
||||
|
||||
[SerializeField]
|
||||
public GameObject mapPrefab;
|
||||
|
||||
private Dictionary<Vector2Int, GameObject> map_collection; //coordinates -> GO
|
||||
|
||||
|
||||
|
||||
//viewable area of the current map_collection.
|
||||
public int max_X, max_Y;
|
||||
public int min_X, min_Y;
|
||||
@@ -33,132 +32,49 @@ namespace Raindrop.UI
|
||||
// 4 - one 256^2 texture is 8*8 sims.
|
||||
public int zoomLevel;
|
||||
|
||||
private void Awake()
|
||||
public MapPoolPresenter(MapSceneView mapSceneView)
|
||||
{
|
||||
this.mapSceneView = mapSceneView;
|
||||
|
||||
max_X = max_Y = max_X = max_Y = 1000;
|
||||
zoomLevel = 1;
|
||||
var map = Instantiate(mapPrefab, new Vector3(0, 0, 0), Quaternion.identity);
|
||||
map_collection.Add(new Vector2Int(1000,1000), map);
|
||||
}
|
||||
|
||||
private void createMapTileAt(Vector2Int pos, int zoomLevel)
|
||||
{
|
||||
var map = Instantiate(mapPrefab, new Vector3(0, 0, 0), Quaternion.identity);
|
||||
map_collection.Add(pos, map);
|
||||
|
||||
|
||||
}
|
||||
private void clearTiles()
|
||||
{
|
||||
map_collection.Clear();
|
||||
|
||||
}
|
||||
|
||||
//private void setViewableRangeMinMax(OpenMetaverse.Vector2 min, OpenMetaverse.Vector2 max)
|
||||
//private void clearTiles()
|
||||
//{
|
||||
// // re-composites the scene based on the viewable region
|
||||
// updateTexturesIfNecessary(min, max);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="focalPoint">Where the camera is looking at - in Sim coordinates*256 ie handle coords. </param>
|
||||
/// <param name="range"></param>
|
||||
public void setViewableRange(OpenMetaverse.Vector2 focalPoint, OpenMetaverse.Vector2 range)
|
||||
{
|
||||
var min = MapLogic.getMinVec2(range, focalPoint);
|
||||
var max = MapLogic.getMaxVec2(range, focalPoint);
|
||||
|
||||
// re-composites the scene based on the viewable region
|
||||
updateTexturesIfNecessary(min, max);
|
||||
}
|
||||
public void setViewableRange(uint x,uint y, OpenMetaverse.Vector2 range)
|
||||
{
|
||||
setViewableRange(new OpenMetaverse.Vector2(x,y), range);
|
||||
}
|
||||
|
||||
// min : bottom left
|
||||
// max : top right
|
||||
private void updateTexturesIfNecessary(OpenMetaverse.Vector2 min, OpenMetaverse.Vector2 max)
|
||||
{
|
||||
//'round-up' the corners.
|
||||
int _max_X = (int) Mathf.CeilToInt(max.X);
|
||||
int _max_Y = (int) Mathf.CeilToInt(max.Y);
|
||||
int _min_X = (int) Mathf.CeilToInt(min.X);
|
||||
int _min_Y = (int) Mathf.CeilToInt(min.Y);
|
||||
|
||||
//check if all are in the map.
|
||||
////obtain list of viewable textures.
|
||||
////List<Vector2Int> list = new List<Vector2Int>();
|
||||
for (int i = _min_Y; i <= _max_Y; i++)
|
||||
{
|
||||
for (int j = _min_X; j <= _max_X; j++)
|
||||
{
|
||||
var tocheck = new Vector2Int(j, i);
|
||||
if (! map_collection.ContainsKey(tocheck))
|
||||
{
|
||||
|
||||
}
|
||||
//list.Add( new Vector2Int(j,i) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////sets a map block that is 256pic * 256pic
|
||||
//private void SetMapLayer(Texture2D new_texture, Vector2Int regionXY)
|
||||
//{
|
||||
// Debug.Log("setting the image to the new gameobject");
|
||||
// if (mapManager.map_collection.ContainsKey(regionXY))
|
||||
// {
|
||||
// //update the region.
|
||||
// //MonoBehaviour theGO;
|
||||
// //map_collection.TryGetValue(regionXY, out theGO);
|
||||
|
||||
// //Destroy(theGO.map_tex); //delete the tex2d that is no longer (?) used.
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// GameObject mapGO = new GameObject();
|
||||
// mapGO.transform.SetParent(this.transform);
|
||||
|
||||
// var MR = mapGO.AddComponent<MeshRenderer>();
|
||||
// MR.sharedMaterial = new UnityEngine.Material(Shader.Find("Standard"));
|
||||
// //MR.
|
||||
// var MF = mapGO.AddComponent<MeshFilter>();
|
||||
|
||||
// //generate the plane.
|
||||
// Mesh m = new Mesh();
|
||||
// var width = 1;
|
||||
// var height = 1;
|
||||
// m.vertices = new Vector3[]{
|
||||
// new Vector3(0, 0, 0),
|
||||
// new Vector3(width, 0, 0),
|
||||
// new Vector3(width, height, 0),
|
||||
// new Vector3(0, height, 0)
|
||||
// };
|
||||
// m.uv = new Vector2[]{
|
||||
// new Vector2(0, 0),
|
||||
// new Vector2(0, 1),
|
||||
// new Vector2(1, 1),
|
||||
// new Vector2(1, 0),
|
||||
// };
|
||||
// m.triangles = new int[] { 0, 2, 1, 0, 3, 2 }; //clockwise?
|
||||
// MF.mesh = m;
|
||||
// m.RecalculateBounds();
|
||||
// m.RecalculateNormals();
|
||||
|
||||
// MR.material.mainTexture = new_texture;
|
||||
|
||||
// map_collection.Add(regionXY, mapGO);
|
||||
|
||||
// }
|
||||
|
||||
// map_collection.Clear();
|
||||
|
||||
//}
|
||||
|
||||
//// min : bottom left
|
||||
//// max : top right
|
||||
//private void updateTexturesIfNecessary(OpenMetaverse.Vector2 min, OpenMetaverse.Vector2 max)
|
||||
//{
|
||||
// //'round-up' the corners.
|
||||
// int _max_X = (int) Mathf.CeilToInt(max.X);
|
||||
// int _max_Y = (int) Mathf.CeilToInt(max.Y);
|
||||
// int _min_X = (int) Mathf.CeilToInt(min.X);
|
||||
// int _min_Y = (int) Mathf.CeilToInt(min.Y);
|
||||
|
||||
// //check if all are in the map.
|
||||
// ////obtain list of viewable textures.
|
||||
// ////List<Vector2Int> list = new List<Vector2Int>();
|
||||
// for (int i = _min_Y; i <= _max_Y; i++)
|
||||
// {
|
||||
// for (int j = _min_X; j <= _max_X; j++)
|
||||
// {
|
||||
// var tocheck = new Vector2Int(j, i);
|
||||
// if (! map_collection.ContainsKey(tocheck))
|
||||
// {
|
||||
|
||||
// }
|
||||
// //list.Add( new Vector2Int(j,i) );
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Assets;
|
||||
using OpenMetaverse.Imaging;
|
||||
using Raindrop.Map.Model;
|
||||
using Raindrop.Netcom;
|
||||
using Raindrop.UI;
|
||||
using Raindrop.UI.Views;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UniRx;
|
||||
@@ -12,89 +14,132 @@ using UnityEngine.UI;
|
||||
using Vector2 = UnityEngine.Vector2;
|
||||
using Vector3 = UnityEngine.Vector3;
|
||||
|
||||
namespace Raindrop.Presenters
|
||||
namespace Raindrop.UI.Presenters
|
||||
{
|
||||
// map texture module - root gameobject.
|
||||
|
||||
// this manages the 2d texture objects in the map texture layer
|
||||
// min = bottom left (OM)
|
||||
// max = top right (OM)
|
||||
public class MapPresenter : MonoBehaviour
|
||||
public class MapPresenter
|
||||
{
|
||||
//camera. contains the viewable range.
|
||||
[SerializeField]
|
||||
public GameObject cameraPresenterGO;
|
||||
private StationaryDownwardOrthoCameraPresenter cameraPresenter;
|
||||
|
||||
//map mover. Contains focal point. Moves focal point in response to screen swipes.
|
||||
[SerializeField]
|
||||
public GameObject mapMoverGO;
|
||||
private MapMover mapMover;
|
||||
//public OpenMetaverse.Vector2 focalPoint;
|
||||
//public Transform mapOrigin; // 1000,1000
|
||||
|
||||
// map manager. keeps track of mapsGOs. creates new mapGOs from prefabs. culls those that are no longer visible. fetches those that need to be viewed.
|
||||
[SerializeField]
|
||||
public GameObject mapManagerGO;
|
||||
private MapPoolPresenter mapManager;
|
||||
|
||||
// a reference to the avatar in the grid.
|
||||
public GameObject Avatar;
|
||||
private MapViewer mapViewer;
|
||||
private MapSceneView mapSceneView;
|
||||
private MapBackend mapFetcher;
|
||||
private bool needRepaint;
|
||||
|
||||
private RaindropInstance instance { get { return ServiceLocator.ServiceLocator.Instance.Get<RaindropInstance>(); } }
|
||||
private RaindropNetcom netcom { get { return instance.Netcom; } }
|
||||
private GridClient client { get { return instance.Client; } }
|
||||
bool Active => instance.Client.Network.Connected;
|
||||
|
||||
|
||||
|
||||
public void Awake()
|
||||
/// <summary>
|
||||
/// ctor -- takes in a UI view and a gameobject view
|
||||
/// </summary>
|
||||
/// <param name="mapViewer"></param>
|
||||
public MapPresenter(MapViewer mapViewer, MapSceneView mapSceneView)
|
||||
{
|
||||
this.mapViewer = mapViewer;
|
||||
this.mapSceneView = mapSceneView;
|
||||
|
||||
if (cameraPresenterGO == null)
|
||||
{
|
||||
throw new Exception("cameraPresenterGO not assigned.");
|
||||
}
|
||||
cameraPresenter = cameraPresenterGO.GetComponent<StationaryDownwardOrthoCameraPresenter>();
|
||||
|
||||
if (mapMoverGO == null)
|
||||
{
|
||||
throw new Exception("MapMoverGO not assigned.");
|
||||
}
|
||||
mapMover = mapMover.GetComponent<MapMover>();
|
||||
|
||||
if (mapManagerGO == null)
|
||||
{
|
||||
throw new Exception("mapManagerGO not assigned.");
|
||||
}
|
||||
mapManager = mapManager.GetComponent<MapPoolPresenter>();
|
||||
|
||||
|
||||
//instance.Client.Network.SimChanged += Network_OnCurrentSimChanged;
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
UpdateMapViewing();
|
||||
//mapFetcher = ServiceLocator.ServiceLocator.Instance.Get<MapBackend>();
|
||||
mapFetcher = new MapBackend();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Update what is viewable and what is not.
|
||||
/// get a list of region handles that are visible to the camera.
|
||||
/// </summary>
|
||||
private void UpdateMapViewing()
|
||||
/// <returns></returns>
|
||||
public List<ulong> calcVisibleRegionHandles()
|
||||
{
|
||||
var range = cameraPresenter.getRange(); // we can see this ranges now.
|
||||
ulong focalPoint = mapMover.GetLookAt();
|
||||
uint x;
|
||||
uint y;
|
||||
//var min = MapLogic.getMinVec2(range, focalPoint);
|
||||
//var max = MapLogic.getMaxVec2(range, focalPoint);
|
||||
Utils.LongToUInts(focalPoint, out x, out y);
|
||||
mapManager.setViewableRange(x, y, range);
|
||||
// camera pos
|
||||
CameraView camView = mapSceneView.getCameraView();
|
||||
// camera bounds
|
||||
Vector2 min = Vector2.Max(camView.getMin(), Vector2.zero);
|
||||
Vector2 max = Vector2.Max(camView.getMax(), Vector2.zero);
|
||||
// for loop from bounds to bounds.
|
||||
List<ulong> visiblehandles = new List<ulong>();
|
||||
int vert_min = (int) min.y;
|
||||
int vert_max = (int) max.y;
|
||||
int horz_min = (int) min.x;
|
||||
int horz_max = (int) max.x;
|
||||
for (int i = horz_min; i<horz_max; i++)
|
||||
{
|
||||
for (int j = vert_min; j < vert_max ; j++)
|
||||
{
|
||||
ulong region = Utils.UIntsToLong((uint)(i * 256), (uint)(j * 256));
|
||||
visiblehandles.Add(region);
|
||||
}
|
||||
}
|
||||
|
||||
if (visiblehandles.Count > 30)
|
||||
{
|
||||
throw new Exception("too many tiles to downlaod bro!");
|
||||
}
|
||||
|
||||
return visiblehandles;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves desired tile from backend. if not present, tiles will be fetched and come in at a later time.
|
||||
/// </summary>
|
||||
public void onRefresh()
|
||||
{
|
||||
var handles = calcVisibleRegionHandles();
|
||||
|
||||
foreach(var handle in handles)
|
||||
{
|
||||
var tile = mapFetcher.tryGetMapTile(handle, 1);
|
||||
|
||||
if (tile == null)
|
||||
{
|
||||
//not avail in backend so fetch it.
|
||||
mapFetcher.GetRegionTileExternal(handle, 1);
|
||||
Debug.Log("fetching texture at " + handle);
|
||||
} else
|
||||
{
|
||||
//if (mapSceneView.isPresent(handle))
|
||||
//{
|
||||
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
mapSceneView.createMapTileAt(handle, tile);
|
||||
Debug.Log("making tile at " + handle);
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Debug.Log("refreshed internal images. fetching images if any..");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Redraws the tiles if the redraw flag is true.
|
||||
/// </summary>
|
||||
//private void redrawMap()
|
||||
//{
|
||||
// //onRefresh(); //hacky
|
||||
|
||||
// if (needRepaint)
|
||||
// {
|
||||
// needRepaint = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// ulong handle = mapLookAt.GetLookAt();
|
||||
// MapTile tex = mapFetcher.tryGetMapTile(handle, 1);
|
||||
|
||||
// if (tex != null)
|
||||
// {
|
||||
// mapSceneView.setRawImage(tex.getTex());
|
||||
// }
|
||||
// Debug.Log("drew images.");
|
||||
//}
|
||||
|
||||
//private void Network_OnCurrentSimChanged(object sender, SimChangedEventArgs e)
|
||||
//{
|
||||
|
||||
@@ -134,7 +179,7 @@ namespace Raindrop.Presenters
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &4388118593235937986
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8521627812515242652}
|
||||
- component: {fileID: 13259539368458950}
|
||||
m_Layer: 0
|
||||
m_Name: MapTile
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &8521627812515242652
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4388118593235937986}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 7392048557130180065}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &13259539368458950
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4388118593235937986}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 866e029c2878fad448f745025e9b4341, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
texturableGO: {fileID: 8388067586253381780}
|
||||
--- !u!1 &8388067586253381780
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7392048557130180065}
|
||||
- component: {fileID: 5605264082212299153}
|
||||
- component: {fileID: 6124680892397115969}
|
||||
m_Layer: 0
|
||||
m_Name: Texture
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &7392048557130180065
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8388067586253381780}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0.5, y: 0, z: 0.5}
|
||||
m_LocalScale: {x: 0.095, y: 0.095, z: 0.095}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8521627812515242652}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!23 &5605264082212299153
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8388067586253381780}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 0}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!33 &6124680892397115969
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8388067586253381780}
|
||||
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4486e9d963742a4a8db3b183db0b919
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Raindrop.Presenters
|
||||
{
|
||||
// An implementation of view. Attach to GO that has rawimage.
|
||||
// refers to a single texture; a single tile. can refer to many sims on a single tile.
|
||||
[RequireComponent(typeof(RawImage))]
|
||||
public class MapTileView : MonoBehaviour
|
||||
{
|
||||
public void setRawImage(Texture2D img)
|
||||
{
|
||||
//hack: delete old texture before loading new one
|
||||
|
||||
if (this.GetComponent<RawImage>().texture != null)
|
||||
{
|
||||
UnityEngine.Object.Destroy(this.GetComponent<RawImage>().texture);
|
||||
}
|
||||
this.GetComponent<RawImage>().texture = img;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59e42b8c540ce4445b9fccf366228e7d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76f29b6b41aed5d45b8906710ed251d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,167 @@
|
||||
using OpenMetaverse;
|
||||
using Raindrop.Network;
|
||||
using Raindrop.UI;
|
||||
using ServiceLocator;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Raindrop.Map.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains logic to fetch and decode the map textures.
|
||||
/// </summary>
|
||||
|
||||
//backend image fetch logic
|
||||
|
||||
|
||||
|
||||
// map fetching class.
|
||||
// contains a dict for tracking the tile maps.
|
||||
// contains the reusable pool to discard and recycle tile maps.
|
||||
public class MapBackend : IGameService
|
||||
{
|
||||
MapTilesManager mapTilesManager;
|
||||
List<ulong> tileRequests = new List<ulong>(); // a list of pending fetch requests. the ulongs are the x and y world coordinates (gridX * 256), packed.
|
||||
uint regionSize = 256;
|
||||
private ParallelDownloader downloader;
|
||||
int poolSize = 10;
|
||||
|
||||
UnityMainThreadDispatcher mainThreadInstance;
|
||||
|
||||
public MapBackend()
|
||||
{
|
||||
mapTilesManager = new MapTilesManager(10);
|
||||
|
||||
downloader = new ParallelDownloader();
|
||||
|
||||
mainThreadInstance = UnityMainThreadDispatcher.Instance();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API to Get the map tile at specific region handle and zoom level. Only zoom level 1 is supported.
|
||||
/// gets the map tile at handle if present.
|
||||
/// if not present, a webrequest for the tile will be made. a notification of download success will not be reported to the caller of this function.
|
||||
/// </summary>
|
||||
/// <param name="handle"></param>
|
||||
/// <param name="zoom"></param>
|
||||
/// <returns></returns>
|
||||
public MapTile tryGetMapTile(ulong handle, int zoom)
|
||||
{
|
||||
MapTile res = null;
|
||||
|
||||
//try
|
||||
//{
|
||||
res = mapTilesManager.tryGetTile(handle);
|
||||
//}
|
||||
//catch (Exception)
|
||||
//{
|
||||
//uint x, y;
|
||||
//Utils.LongToUInts(handle, out x, out y);
|
||||
//Debug.LogError("no tile found at " + x + " " + y);
|
||||
//}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//get region tile using SL map API -- JPEG images.
|
||||
// obtains the image from URL, decodes it in main thread, the stores data in the appropriate maptile.
|
||||
public MapTile GetRegionTileExternal(ulong handle, int zoom)
|
||||
{
|
||||
if ((zoom > 4) || (zoom < 1))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (tryGetMapTile(handle, 1) != null)
|
||||
{
|
||||
return tryGetMapTile(handle, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (tileRequests)
|
||||
{
|
||||
if (tileRequests.Contains(handle)) return null;
|
||||
tileRequests.Add(handle);
|
||||
}
|
||||
|
||||
uint regX, regY;
|
||||
Utils.LongToUInts(handle, out regX, out regY);
|
||||
regX /= regionSize;
|
||||
regY /= regionSize;
|
||||
//int zoom = 1;
|
||||
|
||||
downloader.QueueDownlad(
|
||||
new Uri(string.Format("http://map.secondlife.com/map-{0}-{1}-{2}-objects.jpg", zoom, regX, regY)),
|
||||
20 * 1000,
|
||||
null,
|
||||
null,
|
||||
(request, response, responseData, error) =>
|
||||
{
|
||||
if (error == null && responseData != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Log("fetching the texture was successful!");
|
||||
|
||||
//lock (mapData.sceneTiles)
|
||||
//{
|
||||
//decode http response data into texture2d
|
||||
//MapTile tex = mapData.getTile();
|
||||
MapTile tile = mapTilesManager.setEmptyTile(handle); //Tile is a empty tile right now -- we write to it soon.
|
||||
|
||||
//run jpeg decoding on the main thread, for now.
|
||||
mainThreadInstance.Enqueue(DecodeDataToTexAsync(tile, responseData));
|
||||
|
||||
//set the tile into tile manager
|
||||
//mapTilesManager.setTile(handle, tile);
|
||||
//}
|
||||
|
||||
lock (tileRequests)
|
||||
if (tileRequests.Contains(handle))
|
||||
tileRequests.Remove(handle);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
//lock (mapData.sceneTiles)
|
||||
//{
|
||||
// mapData.sceneTiles[handle] = mapData.acquireTile(); //wtf!
|
||||
//}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator DecodeDataToTexAsync(MapTile tex, byte[] responseData)
|
||||
{
|
||||
try
|
||||
{ //check for failed downlaod.
|
||||
Texture2D _tex = tex.getTex();
|
||||
bool success = _tex.LoadImage(responseData);
|
||||
|
||||
}
|
||||
catch (Exception w)
|
||||
{
|
||||
Debug.LogWarning("decode the texture failed : " + w.Message);
|
||||
}
|
||||
Debug.Log("completed mainthread async texture Decode.");
|
||||
|
||||
yield return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58911af2e320c754488a329d38fda964
|
||||
guid: 37eb9ed76f9ebda4d9417f77ea151919
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,7 +1,7 @@
|
||||
using OpenMetaverse;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Raindrop.Map
|
||||
namespace Raindrop.Map.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// A DS that represents a maptile in the scene.
|
||||
+5
-5
@@ -2,12 +2,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raindrop.Map
|
||||
namespace Raindrop.Map.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// API to retrieve, delete, modify, create MapTiles in the scene
|
||||
/// </summary>
|
||||
public class MapDataManager
|
||||
public class MapTilesManager
|
||||
{
|
||||
|
||||
//number of tiles that are in the scene.
|
||||
@@ -16,10 +16,10 @@ namespace Raindrop.Map
|
||||
//tiles that are in the scene.
|
||||
private Dictionary<ulong, MapTile> sceneTiles = new Dictionary<ulong, MapTile>();
|
||||
|
||||
private MapDataPool pool;
|
||||
public MapDataManager(int poolSize)
|
||||
private MapTilesPool pool;
|
||||
public MapTilesManager(int poolSize)
|
||||
{
|
||||
pool = new MapDataPool(poolSize);
|
||||
pool = new MapTilesPool(poolSize);
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,17 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raindrop.Map
|
||||
namespace Raindrop.Map.Model
|
||||
{
|
||||
//pooling pattern for objects -- holds UNUSED map in memory.
|
||||
public class MapDataPool
|
||||
public class MapTilesPool
|
||||
{
|
||||
private Queue<MapTile> tilePool;
|
||||
|
||||
public int count => tilePool.Count;
|
||||
|
||||
|
||||
public MapDataPool(int poolSize)
|
||||
public MapTilesPool(int poolSize)
|
||||
{
|
||||
tilePool = new Queue<MapTile>(poolSize);
|
||||
for (int i = 0; i < poolSize; i++)
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c99728517c04bae4ab466165d1e37fd7
|
||||
guid: 89386530d5358924cb4892b6dd3d0b44
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 820d31c782dc0ef43ba69d3c186ce3d6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78b0cdb4bba7e1248a0945beea1f2533
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5114afc5020e0f42a729803013926ff
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+83
-14
@@ -1,59 +1,115 @@
|
||||
using OpenMetaverse;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Vector2 = OpenMetaverse.Vector2;
|
||||
//using Vector2 = OpenMetaverse.Vector2;
|
||||
using UE = UnityEngine;
|
||||
|
||||
namespace Raindrop.Presenters
|
||||
namespace Raindrop.UI.Views
|
||||
{
|
||||
//the camera no longer moves. however the zoom is still controlled here.
|
||||
//the map moves.
|
||||
internal class StationaryDownwardOrthoCameraPresenter : MonoBehaviour
|
||||
internal class CameraView : MonoBehaviour
|
||||
{
|
||||
public bool isDownward = true;
|
||||
public bool isOrtho = true;
|
||||
|
||||
public GameObject cameraGO;
|
||||
public Camera camera;
|
||||
private Camera camera;
|
||||
|
||||
//map mover. Contains focal point. Moves focal point in response to screen swipes.
|
||||
[SerializeField]
|
||||
public GameObject MapLookAtGO;
|
||||
private MapLookAt mapLookAt;
|
||||
|
||||
private UE.Vector2 min;
|
||||
private UE.Vector2 max;
|
||||
|
||||
/// <summary>
|
||||
/// 2D axes
|
||||
/// </summary>
|
||||
private float centerX => this.transform.position.x;
|
||||
private float centerY => this.transform.position.z;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
//viewableSize = camera.orthographicSize; //orthographicSize is half the size of the vertical viewing volume.
|
||||
init();
|
||||
//mapLookAt = mapLookAt.GetComponent<MapLookAt>();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the zoom of the orth camera. a value of 1 means that the height of the viewing is 1. a value of 10 means the height of the viewing is 10.
|
||||
/// </summary>
|
||||
/// <param name="zoom"></param>
|
||||
public void setZoom(float zoom)
|
||||
{
|
||||
var maxZoom = 10;
|
||||
zoom = Mathf.Clamp(zoom, 1, maxZoom);
|
||||
setVertHeight(zoom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get the viewable range (height and width) of the camera as x,y tuple. Units are in orthographic units.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public OpenMetaverse.Vector2 getRange()
|
||||
//public OpenMetaverse.Vector2 getRange()
|
||||
//{
|
||||
// return new Vector2(getHorzRange(), getVertRange());
|
||||
//}
|
||||
|
||||
|
||||
|
||||
/// <returns></returns>
|
||||
/// <summary>
|
||||
/// In unity units. -- you need to x256
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public UE.Vector2 getMin()
|
||||
{
|
||||
return new Vector2(getHorzRange(), getVertRange());
|
||||
var pos_x = centerX - getHorzRange();
|
||||
var pos_y = centerY - getVertRange();
|
||||
|
||||
min.Set(pos_x, pos_y);
|
||||
return min;
|
||||
}
|
||||
|
||||
// get the vertical height of the camera as float.
|
||||
public float getVertHeight()
|
||||
/// <summary>
|
||||
/// In unity units. -- you need to x256
|
||||
/// </summary>
|
||||
public UE.Vector2 getMax()
|
||||
{
|
||||
return camera.orthographicSize;
|
||||
var pos_x = centerX + getHorzRange();
|
||||
var pos_y = centerY + getVertRange();
|
||||
|
||||
max.Set(pos_x, pos_y);
|
||||
return max;
|
||||
}
|
||||
|
||||
// set the vertical height of the camera as float.
|
||||
public void setVertHeight(float height)
|
||||
private void setVertHeight(float height)
|
||||
{
|
||||
camera.orthographicSize = height;
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the complete height of the camera. (top-down.)
|
||||
/// Get the half-height of the camera.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private float getVertRange()
|
||||
{
|
||||
return camera.orthographicSize * 2;
|
||||
return camera.orthographicSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the complete width of the camera. (left-right)
|
||||
/// Get the half-width of the ortho camera.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private float getHorzRange()
|
||||
{
|
||||
return camera.orthographicSize * 2 * camera.aspect;
|
||||
return camera.orthographicSize * camera.aspect;
|
||||
}
|
||||
|
||||
////these coordinate differences are quite condfusing.
|
||||
@@ -87,6 +143,9 @@ namespace Raindrop.Presenters
|
||||
// _updateCameraPos(gridX, gridY);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Initilise camera with relevant params
|
||||
/// </summary>
|
||||
internal void init()
|
||||
{
|
||||
if (cameraGO == null || !cameraGO.GetComponent<Camera>())
|
||||
@@ -97,6 +156,16 @@ namespace Raindrop.Presenters
|
||||
}
|
||||
camera = cameraGO.GetComponent<Camera>();
|
||||
|
||||
//if (isDownward)
|
||||
//{
|
||||
// cameraGO.transform.LookAt(transform.position + UnityEngine.Vector3.down);
|
||||
//}
|
||||
|
||||
//if (isOrtho)
|
||||
//{
|
||||
// camera.orthographic = true;
|
||||
//}
|
||||
|
||||
//cameraGO = new GameObject();
|
||||
//camera = cameraGO.AddComponent<Camera>();
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Raindrop;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace Raindrop.UI.Views
|
||||
{
|
||||
//an instance of a map 'look at' ; the focal point of camera.
|
||||
public class MapLookAt : MonoBehaviour
|
||||
{
|
||||
//grid coordinates * 256
|
||||
[SerializeField]
|
||||
public uint lookAt_x => Convert.ToUInt32(floatingLookAt_x * 256); //1000 * 256;
|
||||
[SerializeField]
|
||||
public uint lookAt_y => Convert.ToUInt32(floatingLookAt_y * 256); //1000 * 256;
|
||||
|
||||
//grid coordinates * 1
|
||||
[SerializeField]
|
||||
private float floatingLookAt_x = 1000;
|
||||
[SerializeField]
|
||||
private float floatingLookAt_y = 1000;
|
||||
|
||||
//values when the finger is not released yet.
|
||||
[SerializeField]
|
||||
public float prev_floatingLookAt_x = 1000;
|
||||
[SerializeField]
|
||||
public float prev_floatingLookAt_y = 1000;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// get lookat of the camera in ( gridCoord * 256 ) units
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
public ulong GetLookAt()
|
||||
{
|
||||
return Utils.UIntsToLong(lookAt_x, lookAt_y);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move the *floating* lookAt by this amount.
|
||||
/// moves by an relative amount - that is, all parameters of this call parameters are relative to the *inital touch location*.
|
||||
/// </summary>
|
||||
/// <param name="x">change of x - in units where there are 256 units per Sim. </param>
|
||||
/// <param name="y"></param>
|
||||
public void MoveFloatingLookAt_Relative(float x, float y)
|
||||
{
|
||||
floatingLookAt_x = prev_floatingLookAt_x + x;
|
||||
floatingLookAt_y = prev_floatingLookAt_y + y;
|
||||
|
||||
Debug.Log(x);
|
||||
Debug.Log(y);
|
||||
|
||||
updateThisPos(floatingLookAt_x, floatingLookAt_y);
|
||||
}
|
||||
|
||||
private void updateThisPos(float floatingLookAt_x, float floatingLookAt_y)
|
||||
{
|
||||
this.transform.position = new UnityEngine.Vector3(floatingLookAt_x, this.transform.position.x, floatingLookAt_y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the lookAt to a final position. Call this when the finger is released.
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
public void MoveFloatingLookAt_Relative_OnRelease(float x, float y)
|
||||
{
|
||||
floatingLookAt_x = prev_floatingLookAt_x + x;
|
||||
floatingLookAt_y = prev_floatingLookAt_y + y;
|
||||
|
||||
prev_floatingLookAt_x = floatingLookAt_x;
|
||||
prev_floatingLookAt_y = floatingLookAt_y;
|
||||
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f157d1bbe73dcd6478c48641516b668a
|
||||
guid: 62bf8cfe3c16b714ab5198060c130f89
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using Raindrop.Map;
|
||||
using OpenMetaverse;
|
||||
using UE = UnityEngine;
|
||||
using Raindrop.Map.Model;
|
||||
using Raindrop.Presenters;
|
||||
|
||||
namespace Raindrop.UI.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// the view that is in the root of the map layer/ map scene.
|
||||
/// - instantiates map tile prefabs.
|
||||
/// - keeps track of the map tiles in a dict.
|
||||
/// - contains the camera
|
||||
/// </summary>
|
||||
|
||||
public class MapSceneView : MonoBehaviour
|
||||
{
|
||||
private MapPoolPresenter mapPoolPresenter;
|
||||
|
||||
|
||||
[SerializeField]
|
||||
public GameObject mapPrefab;
|
||||
|
||||
//camera. contains the viewable range.
|
||||
[SerializeField]
|
||||
public GameObject cameraViewGO;
|
||||
private CameraView cameraView;
|
||||
|
||||
private Dictionary<ulong, GameObject> map_collection = new Dictionary<ulong, GameObject>(); //tiles that are in the scene.
|
||||
|
||||
|
||||
//viewable area of the current map_collection.
|
||||
public int max_X, max_Y;
|
||||
public int min_X, min_Y;
|
||||
|
||||
//the current zoom level that the user is requesting.
|
||||
// 1 - one 256^2 texture is 1 sim.
|
||||
// ...
|
||||
// 4 - one 256^2 texture is 8*8 sims.
|
||||
public int zoomLevel;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
|
||||
cameraView = cameraViewGO.GetComponent<CameraView>();
|
||||
|
||||
mapPoolPresenter = new MapPoolPresenter(this);
|
||||
|
||||
max_X = max_Y = max_X = max_Y = 1000;
|
||||
zoomLevel = 1;
|
||||
}
|
||||
|
||||
|
||||
//private UE.Vector2Int handleToVector2(ulong handle)
|
||||
//{
|
||||
// uint x, y;
|
||||
// Utils.LongToUInts(handle, out x, out y);
|
||||
// return new UnityEngine.Vector2Int((int)x, (int)y);
|
||||
//}
|
||||
|
||||
public void createMapTileAt(ulong handle, MapTile tile)
|
||||
{
|
||||
//var pos = handleToVector2(handle);
|
||||
|
||||
UE.Vector3 posInScene = toV3(handle);
|
||||
|
||||
var map = Instantiate(mapPrefab, posInScene, UE.Quaternion.identity);
|
||||
map_collection.Add(handle, map);
|
||||
|
||||
map.GetComponent<MapTileView>().setRawImage(tile.getTex());
|
||||
}
|
||||
|
||||
private UE.Vector3 toV3(ulong handle)
|
||||
{
|
||||
uint x, y;
|
||||
Utils.LongToUInts(handle, out x, out y);
|
||||
|
||||
return new UE.Vector3(x/256, 0, y/256);
|
||||
}
|
||||
|
||||
internal CameraView getCameraView()
|
||||
{
|
||||
return cameraView;
|
||||
}
|
||||
|
||||
private void clearTiles()
|
||||
{
|
||||
map_collection.Clear();
|
||||
|
||||
}
|
||||
|
||||
internal bool isPresent(ulong handle)
|
||||
{
|
||||
//var pos = handleToVector2(handle);
|
||||
return map_collection.ContainsKey(handle);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="focalPoint">Where the camera is looking at - in Sim coordinates*256 ie handle coords. </param>
|
||||
/// <param name="range"></param>
|
||||
//public void setViewableRange(OpenMetaverse.Vector2 focalPoint, OpenMetaverse.Vector2 range)
|
||||
//{
|
||||
// var min = MapBackend.getMinVec2(range, focalPoint);
|
||||
// var max = MapBackend.getMaxVec2(range, focalPoint);
|
||||
|
||||
// // re-composites the scene based on the viewable region
|
||||
// updateTexturesIfNecessary(min, max);
|
||||
//}
|
||||
//public void setViewableRange(uint x,uint y, OpenMetaverse.Vector2 range)
|
||||
//{
|
||||
// setViewableRange(new OpenMetaverse.Vector2(x,y), range);
|
||||
//}
|
||||
|
||||
|
||||
////sets a map block that is 256pic * 256pic
|
||||
//private void SetMapLayer(Texture2D new_texture, Vector2Int regionXY)
|
||||
//{
|
||||
// Debug.Log("setting the image to the new gameobject");
|
||||
// if (mapManager.map_collection.ContainsKey(regionXY))
|
||||
// {
|
||||
// //update the region.
|
||||
// //MonoBehaviour theGO;
|
||||
// //map_collection.TryGetValue(regionXY, out theGO);
|
||||
|
||||
// //Destroy(theGO.map_tex); //delete the tex2d that is no longer (?) used.
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// GameObject mapGO = new GameObject();
|
||||
// mapGO.transform.SetParent(this.transform);
|
||||
|
||||
// var MR = mapGO.AddComponent<MeshRenderer>();
|
||||
// MR.sharedMaterial = new UnityEngine.Material(Shader.Find("Standard"));
|
||||
// //MR.
|
||||
// var MF = mapGO.AddComponent<MeshFilter>();
|
||||
|
||||
// //generate the plane.
|
||||
// Mesh m = new Mesh();
|
||||
// var width = 1;
|
||||
// var height = 1;
|
||||
// m.vertices = new Vector3[]{
|
||||
// new Vector3(0, 0, 0),
|
||||
// new Vector3(width, 0, 0),
|
||||
// new Vector3(width, height, 0),
|
||||
// new Vector3(0, height, 0)
|
||||
// };
|
||||
// m.uv = new Vector2[]{
|
||||
// new Vector2(0, 0),
|
||||
// new Vector2(0, 1),
|
||||
// new Vector2(1, 1),
|
||||
// new Vector2(1, 0),
|
||||
// };
|
||||
// m.triangles = new int[] { 0, 2, 1, 0, 3, 2 }; //clockwise?
|
||||
// MF.mesh = m;
|
||||
// m.RecalculateBounds();
|
||||
// m.RecalculateNormals();
|
||||
|
||||
// MR.material.mainTexture = new_texture;
|
||||
|
||||
// map_collection.Add(regionXY, mapGO);
|
||||
|
||||
// }
|
||||
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 327f1fb8354daac46abcf57544d8c82e
|
||||
guid: b1eb66cf6e85f814f8370584e7b8fa03
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Raindrop.Presenters
|
||||
{
|
||||
// An implementation of view. Attach to GO that has rawimage.
|
||||
// refers to a single texture; a single tile. can refer to many sims on a single tile.
|
||||
//[RequireComponent(typeof(RawImage))]
|
||||
|
||||
|
||||
public class MapTileView : MonoBehaviour
|
||||
{
|
||||
public GameObject texturableGO;
|
||||
private UnityEngine.Object texturableObj;
|
||||
|
||||
public void setRawImage(Texture2D img)
|
||||
{
|
||||
//hack: delete old texture before loading new one
|
||||
|
||||
if (texturableObj != null)
|
||||
{
|
||||
UnityEngine.Object.Destroy(texturableObj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
setTex(img);
|
||||
|
||||
}
|
||||
|
||||
private void setTex(Texture2D img)
|
||||
{
|
||||
if (texturableGO.GetComponent<RawImage>() != null)
|
||||
{
|
||||
texturableObj = texturableGO.GetComponent<RawImage>().mainTexture; //rawimage
|
||||
texturableObj = img;
|
||||
}
|
||||
|
||||
if (texturableGO.GetComponent<MeshRenderer>() != null)
|
||||
{
|
||||
texturableObj = texturableGO.GetComponent<MeshRenderer>().material.mainTexture; //texture2d
|
||||
texturableObj = img;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (texturableGO.GetComponent<RawImage>() != null)
|
||||
{
|
||||
texturableObj = texturableGO.GetComponent<RawImage>().mainTexture; //rawimage
|
||||
}
|
||||
|
||||
if (texturableGO.GetComponent<MeshRenderer>() != null)
|
||||
{
|
||||
texturableObj = texturableGO.GetComponent<MeshRenderer>().material.mainTexture; //texture2d
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using Better.StreamingAssets;
|
||||
using System;
|
||||
using Raindrop;
|
||||
using UnityEngine.UI;
|
||||
using Raindrop.Presenters;
|
||||
using OpenMetaverse;
|
||||
using Raindrop.Map;
|
||||
using Raindrop.UI;
|
||||
using Raindrop.UI.Presenters;
|
||||
|
||||
|
||||
// lets you view the maps by choosing parameters.
|
||||
// use external API. does not need login.
|
||||
|
||||
namespace Raindrop.UI.Views
|
||||
{
|
||||
public class MapViewer : MonoBehaviour
|
||||
{
|
||||
|
||||
// map manager. keeps track of mapsGOs. creates new mapGOs from prefabs. culls those that are no longer visible. fetches those that need to be viewed.
|
||||
[SerializeField]
|
||||
public GameObject mapSceneViewGO;
|
||||
private MapSceneView mapSceneView;
|
||||
|
||||
|
||||
[SerializeField]
|
||||
public GameObject zoomSliderGO;
|
||||
private Slider zoomSlider;
|
||||
|
||||
|
||||
private MapPresenter presenter;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
mapSceneView = mapSceneViewGO.GetComponent<MapSceneView>();
|
||||
|
||||
//get reference to the view.
|
||||
zoomSlider = zoomSliderGO.GetComponent<Slider>();
|
||||
if (zoomSlider == null)
|
||||
{
|
||||
Debug.LogWarning("slider is fucked"); // fix exception type plz
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
//redrawMap();
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
presenter = new MapPresenter(this, mapSceneView);
|
||||
InvokeRepeating("redrawMap", 5f, 5f);
|
||||
}
|
||||
|
||||
|
||||
private void redrawMap()
|
||||
{
|
||||
presenter.onRefresh(); //retrieve tiles and redraw.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86bd9e369dde9514caa91b4db33a0d55
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,94 +0,0 @@
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using Raindrop;
|
||||
using Raindrop.Netcom;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using Settings = Raindrop.Settings;
|
||||
using UnityEngine.UI;
|
||||
using UniRx;
|
||||
using TMPro;
|
||||
|
||||
|
||||
//view(unitytext) -- presenter(this) -- controller(this?) -- model (raindropinstance singleton)
|
||||
|
||||
public class MapPresenter : MonoBehaviour
|
||||
{
|
||||
|
||||
private RaindropInstance instance { get { return ServiceLocator.ServiceLocator.Instance.Get<RaindropInstance>(); } }
|
||||
private RaindropNetcom netcom { get { return instance.Netcom; } }
|
||||
bool Active => instance.Client.Network.Connected;
|
||||
|
||||
|
||||
#region references to UI elements
|
||||
public Button ChatButton;
|
||||
public Button MapButton;
|
||||
public Image MapPane;
|
||||
public TMP_Text locationText;
|
||||
|
||||
public Canvas joyCanvas;
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal representations
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region behavior
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
initialiseFields();
|
||||
|
||||
ChatButton.onClick.AsObservable().Subscribe(_ => OnChatBtnClick()); //when clicked, runs this method.
|
||||
MapButton.onClick.AsObservable().Subscribe(_ => OnChatBtnClick()); //when clicked, runs this method.
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void showModal(string v, string message)
|
||||
{
|
||||
|
||||
Debug.Log("MODAL:\n" + v + "\n" +message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void initialiseFields()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void OnChatBtnClick()
|
||||
{
|
||||
//instance.UI.canvasManager.pushCanvas(CanvasType.Chat);
|
||||
|
||||
|
||||
}
|
||||
public void OnMapBtnClick()
|
||||
{
|
||||
//instance.UI.canvasManager.pushCanvas(CanvasType.Map);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+11
-9
@@ -9,14 +9,16 @@ using UnityEngine.UI;
|
||||
using Raindrop.Presenters;
|
||||
using OpenMetaverse;
|
||||
using Raindrop.Map;
|
||||
using Raindrop.Map.Model;
|
||||
using Raindrop.UI.Views;
|
||||
|
||||
// lets you view the maps by choosing parameters.
|
||||
// use external API. does not need login.
|
||||
public class MapViewer : MonoBehaviour
|
||||
public class MapViewer_SingleStatic_NoZoom : MonoBehaviour
|
||||
{
|
||||
|
||||
[SerializeField]
|
||||
public MapLogic.MapFetcher mapFetcher;
|
||||
public MapBackend mapFetcher;
|
||||
|
||||
[SerializeField]
|
||||
public GameObject mapTileGO;
|
||||
@@ -28,7 +30,7 @@ public class MapViewer : MonoBehaviour
|
||||
|
||||
[SerializeField]
|
||||
public GameObject mapMoverGO;
|
||||
private MapMover mapMover;
|
||||
private MapLookAt mapMover;
|
||||
|
||||
private float timeStart;
|
||||
private int imagesCount;
|
||||
@@ -39,7 +41,7 @@ public class MapViewer : MonoBehaviour
|
||||
System.Threading.Timer repaint;
|
||||
private void Awake()
|
||||
{
|
||||
mapFetcher = new MapLogic.MapFetcher();
|
||||
mapFetcher = new MapBackend();
|
||||
|
||||
}
|
||||
|
||||
@@ -64,17 +66,17 @@ public class MapViewer : MonoBehaviour
|
||||
zoomSlider = zoomSliderGO.GetComponent<Slider>();
|
||||
if (zoomSlider == null)
|
||||
{
|
||||
throw new System.Exception("slider is fucked"); // fix exception type plz
|
||||
Debug.LogWarning("slider is fucked"); // fix exception type plz
|
||||
}
|
||||
|
||||
//get reference to the view.
|
||||
mapMover = mapMoverGO.GetComponent<MapMover>();
|
||||
mapMover = mapMoverGO.GetComponent<MapLookAt>();
|
||||
if (mapMover == null)
|
||||
{
|
||||
throw new System.Exception("mapMoverGO is fucked"); // fix exception type plz
|
||||
}
|
||||
|
||||
mapFetcher = new MapLogic.MapFetcher();
|
||||
mapFetcher = new MapBackend();
|
||||
|
||||
|
||||
// for testing
|
||||
@@ -89,7 +91,7 @@ public class MapViewer : MonoBehaviour
|
||||
ulong handle = mapMover.GetLookAt();
|
||||
int zoom = (int)zoomSlider.value;
|
||||
// how 2 convert look at floats into uints? (uints are gridpos * 256)
|
||||
if (mapFetcher.GetMapTile(handle, 1) == null) //hack for now.
|
||||
if (mapFetcher.tryGetMapTile(handle, 1) == null) //hack for now.
|
||||
{
|
||||
mapFetcher.GetRegionTileExternal(handle, 1);
|
||||
}
|
||||
@@ -115,7 +117,7 @@ public class MapViewer : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
ulong handle = mapMover.GetLookAt();
|
||||
MapTile tex = mapFetcher.GetMapTile(handle, 1);
|
||||
MapTile tex = mapFetcher.tryGetMapTile(handle, 1);
|
||||
|
||||
if (tex != null)
|
||||
{
|
||||
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
using Raindrop.Map;
|
||||
using Raindrop.Map.Model;
|
||||
|
||||
namespace Raindrop
|
||||
{
|
||||
@@ -16,13 +17,13 @@ namespace Raindrop
|
||||
class TestTextureFetcher : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public MapLogic.MapFetcher mapFetcher; //fetching logic + pooling data here
|
||||
public MapBackend mapFetcher; //fetching logic + pooling data here
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
MainThreadDispatcher.Initialize();
|
||||
mapFetcher = new MapLogic.MapFetcher();
|
||||
mapFetcher = new MapBackend();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfb5fdbfcfa159443b08cbacfac1818a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,117 @@
|
||||
using Raindrop.Presenters;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem.EnhancedTouch;
|
||||
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
|
||||
|
||||
|
||||
namespace Raindrop.UI.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// A view that interprets the touch controls.
|
||||
/// </summary>
|
||||
public class PanAndZoomInterpreterModule : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public GameObject objectToMove;
|
||||
private MapLookAt mm;
|
||||
private TouchScreenInteractionInstance fingerInteraction;
|
||||
|
||||
[SerializeField]
|
||||
public GameObject mapCam;
|
||||
private Camera cam;
|
||||
|
||||
[SerializeField]
|
||||
public string layerName = "minimap"; //to project into the 'fake map plane'
|
||||
|
||||
|
||||
private Vector3 worldPoint_startPos;
|
||||
|
||||
|
||||
void Awake()
|
||||
{
|
||||
fingerInteraction = new TouchScreenInteractionInstance();
|
||||
|
||||
mm = objectToMove.GetComponent<MapLookAt>();
|
||||
cam = mapCam.GetComponent<Camera>();
|
||||
|
||||
EnhancedTouchSupport.Enable();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
fingerInteraction.updateInteractionState(); //get new touch data!
|
||||
|
||||
|
||||
if (fingerInteraction.isPan())
|
||||
{
|
||||
var pandelta = fingerInteraction.getPanDelta();
|
||||
mm.MoveFloatingLookAt_Relative(pandelta.x, pandelta.y);
|
||||
}
|
||||
if (fingerInteraction.isZoom())
|
||||
{
|
||||
var zoomdelta = fingerInteraction.getZoomDelta();
|
||||
Debug.Log("2 finger not supported yet!");
|
||||
//mm.MoveFloatingLookAt_Relative(pandelta.x, pandelta.y);
|
||||
}
|
||||
|
||||
if (fingerInteraction.isDifferentInteraction())
|
||||
{
|
||||
//finalise the current-previous interaction.
|
||||
var pandelta = fingerInteraction.getPanDelta();
|
||||
mm.MoveFloatingLookAt_Relative_OnRelease(pandelta.x, pandelta.y);
|
||||
}
|
||||
|
||||
//if (currentState == InteractionState.pan)
|
||||
//{
|
||||
|
||||
// Vector3 ray_touchNow = cam.ScreenToWorldPoint(touchInitialPosition);
|
||||
// if (isTouchBegan)
|
||||
// {
|
||||
// touchInitialPosition = Touch.activeFingers[0].currentTouch.screenPosition;
|
||||
// worldPoint_startPos = cam.ScreenToWorldPoint(touchInitialPosition);
|
||||
// }
|
||||
// else if (isTouchContinue)
|
||||
// {
|
||||
|
||||
// var touchPresentPosition = Touch.activeFingers[0].currentTouch.screenPosition;
|
||||
// Vector3 worldPoint_now = cam.ScreenToWorldPoint(touchInitialPosition);
|
||||
|
||||
|
||||
// var direction = worldPoint_startPos - worldPoint_now;
|
||||
// }
|
||||
// else if (isTouchEnd)
|
||||
// {
|
||||
// Debug.Log("finger lifted and data is set.");
|
||||
// var touchPresentPosition = Touch.activeFingers[0].currentTouch.screenPosition;
|
||||
// Vector3 worldPoint_now = cam.ScreenToWorldPoint(touchInitialPosition);
|
||||
|
||||
|
||||
// var direction = worldPoint_startPos - worldPoint_now;
|
||||
// mm.MoveFloatingLookAt_Relative_OnRelease(direction.x, direction.z);
|
||||
// }
|
||||
|
||||
|
||||
// Touch activeTouch = Touch.activeFingers[0].currentTouch;
|
||||
// Debug.Log($"Phase: {activeTouch.phase} | Position: {activeTouch.startScreenPosition}");
|
||||
|
||||
//} else if (currentState == InteractionState.zoom){
|
||||
|
||||
// if (Touch.activeFingers[1].currentTouch.isInProgress)
|
||||
|
||||
|
||||
// mm.MoveFloatingLookAt_Relative(direction.x, direction.z);
|
||||
|
||||
// Touch activeTouch = Touch.activeFingers[0].currentTouch;
|
||||
// Debug.Log($"Phase: {activeTouch.phase} | Position: {activeTouch.startScreenPosition}");
|
||||
//}
|
||||
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51e20def85a7f5341a71708d6299025e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,189 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
|
||||
|
||||
/// <summary>
|
||||
/// A instance of a user interacting with the screen.
|
||||
/// Responsible for tracking fingers and counting them over their lifecycle.
|
||||
/// Responsible for providing finger zoom delta and finger move delta.
|
||||
/// </summary>
|
||||
public class TouchScreenInteractionInstance
|
||||
{
|
||||
// interaction state.
|
||||
internal enum InteractionType
|
||||
{
|
||||
none, //no touch/ more than 2 fingers
|
||||
zoom, //pinching
|
||||
pan //single finger.
|
||||
}
|
||||
private InteractionType previousType = InteractionType.none;
|
||||
private bool interactionTypeHasChanged = false; // if pan->zoom / none->zoom, etc.
|
||||
|
||||
// internal memory of touches.
|
||||
private List<Vector2> initialTouchPositions = new List<Vector2>(); //each finger's first touch position.
|
||||
private List<Vector2> currentTouchPositions = new List<Vector2>();
|
||||
//private Collider touchFocus; //what we think that the user is touching
|
||||
|
||||
public Vector2 oneFingerMoveDelta { get; private set; }
|
||||
public float twoFingerPinchDelta { get; private set; }
|
||||
public Vector2 twoFingerMoveDelta { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// update the internal status.
|
||||
/// </summary>
|
||||
public void updateInteractionState()
|
||||
{
|
||||
//touch
|
||||
InteractionType presentType = fingerCountToInteractionType(Touch.activeFingers.Count);
|
||||
interactionTypeHasChanged = isStateChanged(previousType, presentType);
|
||||
if (interactionTypeHasChanged)
|
||||
{
|
||||
UpdateInitialFingerPositions();
|
||||
//getProbableTouchFocus();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
updatePresentFingerPositions();
|
||||
updateGlobalAccessibleStates(presentType);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void updateGlobalAccessibleStates(InteractionType presentType)
|
||||
{
|
||||
if (presentType == InteractionType.zoom)
|
||||
{
|
||||
twoFingerPinchDelta = Vector2.Distance(initialTouchPositions[0], initialTouchPositions[1]);
|
||||
Vector2 ave_initial = (initialTouchPositions[0] + initialTouchPositions[1]) / 2;
|
||||
Vector2 ave_current = (currentTouchPositions[0] + currentTouchPositions[1]) / 2;
|
||||
|
||||
Vector2 direction = initialTouchPositions[0] - currentTouchPositions[0];
|
||||
twoFingerMoveDelta = direction;
|
||||
}
|
||||
if (presentType == InteractionType.pan)
|
||||
{
|
||||
Vector2 direction = initialTouchPositions[0] - currentTouchPositions[0];
|
||||
oneFingerMoveDelta = direction;
|
||||
}
|
||||
}
|
||||
|
||||
internal InteractionType GetCurrentInteractionState()
|
||||
{
|
||||
return previousType;
|
||||
}
|
||||
|
||||
public bool isDifferentInteraction()
|
||||
{
|
||||
return interactionTypeHasChanged;
|
||||
}
|
||||
|
||||
//private void getProbableTouchFocus()
|
||||
//{
|
||||
// if (Touch.activeFingers.Count == 0)
|
||||
// {
|
||||
// touchFocus = null;
|
||||
// } else
|
||||
// {
|
||||
// Vector2 pos = Touch.activeFingers[0].screenPosition;
|
||||
// touchFocus = pos;
|
||||
|
||||
// worldPoint_startPos = cam.ScreenToWorldPoint(pos);
|
||||
// }
|
||||
//}
|
||||
|
||||
private void updatePresentFingerPositions()
|
||||
{
|
||||
currentTouchPositions.Clear();
|
||||
for (int i = 0; i < Touch.activeFingers.Count; i++)
|
||||
{
|
||||
currentTouchPositions.Add(Touch.activeFingers[i].screenPosition);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateInitialFingerPositions()
|
||||
{
|
||||
initialTouchPositions.Clear();
|
||||
for (int i = 0; i < Touch.activeFingers.Count; i++)
|
||||
{
|
||||
initialTouchPositions.Add(Touch.activeFingers[i].screenPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// convert numberOfFingers into InteractionState
|
||||
/// </summary>
|
||||
/// <param name="fingerCount"></param>
|
||||
/// <returns></returns>
|
||||
private InteractionType fingerCountToInteractionType(int fingerCount)
|
||||
{
|
||||
switch (fingerCount)
|
||||
{
|
||||
case 0:
|
||||
return InteractionType.none;
|
||||
case 1:
|
||||
return InteractionType.pan;
|
||||
case 2:
|
||||
return InteractionType.zoom;
|
||||
default:
|
||||
return InteractionType.none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get the relative zoom change from present zoom (0).
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public float getZoomDelta()
|
||||
{
|
||||
return twoFingerPinchDelta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool isZoom()
|
||||
{
|
||||
return previousType == InteractionType.zoom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get the relative pan change from present pan (0,0).
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Vector2 getPanDelta()
|
||||
{
|
||||
//var direction = touchInitialPosition - worldPoint_now;
|
||||
return oneFingerMoveDelta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool isPan()
|
||||
{
|
||||
return previousType == InteractionType.pan;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if internal 'interaction' state is changed.
|
||||
/// </summary>
|
||||
/// <param name="newState"></param>
|
||||
private bool isStateChanged(InteractionType oldState, InteractionType newState)
|
||||
{
|
||||
if (oldState == newState)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10d7cc6a624c30140bfad11d6b6298b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
+266
-648
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e1b9a8679fd5b54ea34b1e3781f6c3f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class minimapCamera : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
public GameObject lookAt;
|
||||
|
||||
|
||||
|
||||
void Update()
|
||||
{
|
||||
Vector3 newpos = new Vector3( lookAt.transform.position.x, this.transform.position.y, lookAt.transform.position.z) ;
|
||||
this.transform.position = newpos;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f2b9fc291a15c040bb9a8c6e24f30ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -7,6 +7,7 @@
|
||||
"com.unity.ide.rider": "2.0.7",
|
||||
"com.unity.ide.visualstudio": "2.0.11",
|
||||
"com.unity.ide.vscode": "1.2.3",
|
||||
"com.unity.inputsystem": "1.0.2",
|
||||
"com.unity.jobs": "0.8.0-preview.23",
|
||||
"com.unity.memoryprofiler": "0.2.9-preview.3",
|
||||
"com.unity.test-framework": "1.1.27",
|
||||
|
||||
@@ -72,6 +72,13 @@
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.inputsystem": {
|
||||
"version": "1.0.2",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.jobs": {
|
||||
"version": "0.8.0-preview.23",
|
||||
"depth": 0,
|
||||
|
||||
@@ -6,7 +6,7 @@ EditorBuildSettings:
|
||||
serializedVersion: 2
|
||||
m_Scenes:
|
||||
- enabled: 1
|
||||
path: Assets/Scenes/MapViewerTest.unity
|
||||
path: Assets/Scenes/MapViewerTest_Daboom_Basic.unity
|
||||
guid: 07d358068ee106e4ea7053462a2740f3
|
||||
- enabled: 1
|
||||
path: Assets/Scenes/TGALoaderTest.unity
|
||||
|
||||
@@ -775,7 +775,7 @@ PlayerSettings:
|
||||
m_VersionCode: 1
|
||||
m_VersionName:
|
||||
apiCompatibilityLevel: 6
|
||||
activeInputHandler: 0
|
||||
activeInputHandler: 2
|
||||
cloudProjectId:
|
||||
framebufferDepthMemorylessMode: 0
|
||||
qualitySettingsNames: []
|
||||
|
||||
Reference in New Issue
Block a user