working on making the map viewer that can support pan and zoom

This commit is contained in:
alexiscatnip
2021-08-16 00:12:25 +08:00
parent 80bc822868
commit 8085d355ab
53 changed files with 4662 additions and 1312 deletions
+2 -1
View File
@@ -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>();
-282
View File
@@ -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;
// }
// });
// }
//}
}
}
}
-29
View File
@@ -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);
}
}
}
+42 -126
View File
@@ -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) );
// }
// }
//}
}
}
+111 -66
View File
@@ -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
//}
}
+128
View File
@@ -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:
-26
View File
@@ -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;
}
}
}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 59e42b8c540ce4445b9fccf366228e7d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 76f29b6b41aed5d45b8906710ed251d9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+167
View File
@@ -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,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.
@@ -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);
}
@@ -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,5 +1,5 @@
fileFormatVersion: 2
guid: c99728517c04bae4ab466165d1e37fd7
guid: 89386530d5358924cb4892b6dd3d0b44
MonoImporter:
externalObjects: {}
serializedVersion: 2
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 820d31c782dc0ef43ba69d3c186ce3d6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 78b0cdb4bba7e1248a0945beea1f2533
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e5114afc5020e0f42a729803013926ff
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -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>();
+85
View File
@@ -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,5 +1,5 @@
fileFormatVersion: 2
guid: f157d1bbe73dcd6478c48641516b668a
guid: 62bf8cfe3c16b714ab5198060c130f89
MonoImporter:
externalObjects: {}
serializedVersion: 2
+180
View File
@@ -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,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
}
}
}
}
+71
View File
@@ -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
}
@@ -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();
}
+8
View File
@@ -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
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8e1b9a8679fd5b54ea34b1e3781f6c3f
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+17
View File
@@ -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;
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1f2b9fc291a15c040bb9a8c6e24f30ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+1
View File
@@ -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",
+7
View File
@@ -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,
+1 -1
View File
@@ -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
+1 -1
View File
@@ -775,7 +775,7 @@ PlayerSettings:
m_VersionCode: 1
m_VersionName:
apiCompatibilityLevel: 6
activeInputHandler: 0
activeInputHandler: 2
cloudProjectId:
framebufferDepthMemorylessMode: 0
qualitySettingsNames: []