Integrate Aetheria reactive state worktree
This commit is contained in:
parent
426cd8f656
commit
65133ac8a0
61 changed files with 3427 additions and 402 deletions
|
|
@ -25,24 +25,27 @@ public class MapRenderer : MonoBehaviour
|
|||
public Camera InfluenceCamera;
|
||||
public Image OverlayDisplay;
|
||||
public Image GravityDisplay;
|
||||
public Material GravityBackdropMaterial;
|
||||
public Image TintDisplay;
|
||||
public Image InfluenceDisplay;
|
||||
public AetheriaRenderSplatLayerRenderer SplatLayerRenderer;
|
||||
public AetheriaDaemonRenderAssetCatalog AssetCatalog;
|
||||
public RectTransform RtsIconRoot;
|
||||
public RawImage RtsIconPrototype;
|
||||
public float Scale;
|
||||
public float2 Position;
|
||||
public float IconSize = 1f/128;
|
||||
|
||||
private RectTransform _rect;
|
||||
private RenderTexture _mapTexture;
|
||||
private RenderTexture _gravityTexture;
|
||||
private RenderTexture _tintTexture;
|
||||
private RenderTexture _influenceTexture;
|
||||
private int2 _size;
|
||||
private bool _init;
|
||||
private AetheriaClient _client;
|
||||
private string _clientStatePath = "";
|
||||
private AetheriaRuntimeObjectsViewportDocument _objectsViewport;
|
||||
private AetheriaRuntimeGravityViewportDocument _gravityViewport;
|
||||
private AetheriaRuntimeRenderSplatsViewportDocument _renderSplatsViewport;
|
||||
private float _nextViewportRefreshTime;
|
||||
private readonly List<RawImage> _rtsIconPool = new List<RawImage>();
|
||||
|
||||
void Start()
|
||||
{
|
||||
|
|
@ -52,10 +55,16 @@ public class MapRenderer : MonoBehaviour
|
|||
private void OnEnable()
|
||||
{
|
||||
_init = true;
|
||||
MapOverlayCamera.gameObject.SetActive(true);
|
||||
GravityCamera.gameObject.SetActive(true);
|
||||
TintCamera.gameObject.SetActive(true);
|
||||
InfluenceCamera.gameObject.SetActive(true);
|
||||
SetCameraActive(MapOverlayCamera, false);
|
||||
SetCameraActive(GravityCamera, false);
|
||||
SetCameraActive(TintCamera, false);
|
||||
SetCameraActive(InfluenceCamera, false);
|
||||
if (OverlayDisplay != null)
|
||||
OverlayDisplay.gameObject.SetActive(false);
|
||||
if (GravityBackdropMaterial != null && GravityDisplay != null)
|
||||
GravityDisplay.material = GravityBackdropMaterial;
|
||||
EnsureRtsIconRoot();
|
||||
SetRtsIconsActive(true);
|
||||
RefreshViewportDocuments(force: true);
|
||||
|
||||
// If hiding minimap asteroids, turn them back on for the map screen
|
||||
|
|
@ -69,10 +78,13 @@ public class MapRenderer : MonoBehaviour
|
|||
{
|
||||
ReleaseTextures();
|
||||
}
|
||||
MapOverlayCamera.gameObject.SetActive(false);
|
||||
GravityCamera.gameObject.SetActive(false);
|
||||
TintCamera.gameObject.SetActive(false);
|
||||
InfluenceCamera.gameObject.SetActive(false);
|
||||
SetCameraActive(MapOverlayCamera, false);
|
||||
SetCameraActive(GravityCamera, false);
|
||||
SetCameraActive(TintCamera, false);
|
||||
SetCameraActive(InfluenceCamera, false);
|
||||
if (OverlayDisplay != null)
|
||||
OverlayDisplay.gameObject.SetActive(false);
|
||||
SetRtsIconsActive(false);
|
||||
|
||||
// If hiding minimap asteroids, turn them back off when leaving the map screen
|
||||
if (!ResolveShowAsteroidsInMinimap())
|
||||
|
|
@ -88,12 +100,6 @@ public class MapRenderer : MonoBehaviour
|
|||
{
|
||||
_mapTexture.Release();
|
||||
_mapTexture = null;
|
||||
_gravityTexture.Release();
|
||||
_gravityTexture = null;
|
||||
_tintTexture.Release();
|
||||
_tintTexture = null;
|
||||
_influenceTexture.Release();
|
||||
_influenceTexture = null;
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
|
|
@ -108,40 +114,12 @@ public class MapRenderer : MonoBehaviour
|
|||
ReleaseTextures();
|
||||
}
|
||||
|
||||
_mapTexture = new RenderTexture(_size.x, _size.y, 0, RenderTextureFormat.Default);
|
||||
MapOverlayCamera.targetTexture = _mapTexture;
|
||||
OverlayDisplay.material.SetTexture("_DetailTex", _mapTexture);
|
||||
|
||||
_gravityTexture = new RenderTexture(_size.x, _size.y, 0, RenderTextureFormat.RFloat);
|
||||
GravityCamera.targetTexture = _gravityTexture;
|
||||
GravityDisplay.material.SetTexture("_DetailTex", _gravityTexture);
|
||||
|
||||
_tintTexture = new RenderTexture(_size.x / 2, _size.y / 2, 0, RenderTextureFormat.RGB111110Float);
|
||||
TintCamera.targetTexture = _tintTexture;
|
||||
TintDisplay.material.SetTexture("_DetailTex", _tintTexture);
|
||||
|
||||
_influenceTexture = new RenderTexture(_size.x, _size.y, 0, RenderTextureFormat.RFloat);
|
||||
InfluenceCamera.targetTexture = _influenceTexture;
|
||||
InfluenceDisplay.material.SetTexture("_DetailTex", _influenceTexture);
|
||||
}
|
||||
|
||||
var pos = ((Vector2) Position).Flatland(1);
|
||||
|
||||
MapOverlayCamera.transform.position = pos;
|
||||
MapOverlayCamera.orthographicSize = _size.y * Scale * .5f;
|
||||
|
||||
GravityCamera.transform.position = pos;
|
||||
GravityCamera.orthographicSize = _size.y * Scale * .5f;
|
||||
GravityDisplay.material.SetFloat("_Scale", Scale / 2);
|
||||
|
||||
TintCamera.transform.position = pos;
|
||||
TintCamera.orthographicSize = _size.y * Scale * .5f;
|
||||
|
||||
InfluenceCamera.transform.position = pos;
|
||||
InfluenceCamera.orthographicSize = _size.y * Scale * .5f;
|
||||
|
||||
ZoneRenderer.SetIconSize(IconSize * Scale);
|
||||
RefreshViewportDocuments(force: false);
|
||||
RenderSplatLayers();
|
||||
RenderRtsIcons();
|
||||
}
|
||||
|
||||
private void RefreshViewportDocuments(bool force)
|
||||
|
|
@ -158,8 +136,8 @@ public class MapRenderer : MonoBehaviour
|
|||
.ObjectsViewportAsync(viewport)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
_gravityViewport = client
|
||||
.GravityViewportAsync(viewport)
|
||||
_renderSplatsViewport = client
|
||||
.RenderSplatsViewportAsync(viewport)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
|
||||
|
|
@ -175,6 +153,153 @@ public class MapRenderer : MonoBehaviour
|
|||
}
|
||||
}
|
||||
|
||||
private void RenderSplatLayers()
|
||||
{
|
||||
if (_renderSplatsViewport == null)
|
||||
return;
|
||||
|
||||
if (SplatLayerRenderer == null)
|
||||
SplatLayerRenderer = GetComponent<AetheriaRenderSplatLayerRenderer>() ??
|
||||
gameObject.AddComponent<AetheriaRenderSplatLayerRenderer>();
|
||||
|
||||
SplatLayerRenderer.Render(_renderSplatsViewport, _size.x, _size.y);
|
||||
ApplyLayerTexture(AetheriaRuntimeRenderSplatLayerKeys.GravityHeight, GravityDisplay);
|
||||
ApplyLayerTexture(AetheriaRuntimeRenderSplatLayerKeys.FogTint, TintDisplay);
|
||||
ApplyLayerTexture(AetheriaRuntimeRenderSplatLayerKeys.Influence, InfluenceDisplay);
|
||||
}
|
||||
|
||||
private void ApplyLayerTexture(string layerKey, Image display)
|
||||
{
|
||||
if (display == null ||
|
||||
SplatLayerRenderer == null ||
|
||||
!SplatLayerRenderer.TryGetTexture(layerKey, out var texture) ||
|
||||
texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
display.material.SetTexture("_DetailTex", texture);
|
||||
}
|
||||
|
||||
private static void SetCameraActive(Camera camera, bool active)
|
||||
{
|
||||
if (camera != null)
|
||||
camera.gameObject.SetActive(active);
|
||||
}
|
||||
|
||||
private void RenderRtsIcons()
|
||||
{
|
||||
EnsureRtsIconRoot();
|
||||
if (RtsIconRoot == null)
|
||||
return;
|
||||
|
||||
var objects = _objectsViewport?.Objects ?? Array.Empty<AetheriaRuntimeRtsViewportObject>();
|
||||
for (var i = 0; i < objects.Count; i++)
|
||||
{
|
||||
var icon = ResolveRtsIcon(i);
|
||||
ApplyRtsIcon(icon, objects[i]);
|
||||
}
|
||||
|
||||
for (var i = objects.Count; i < _rtsIconPool.Count; i++)
|
||||
if (_rtsIconPool[i] != null)
|
||||
_rtsIconPool[i].gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private RawImage ResolveRtsIcon(int index)
|
||||
{
|
||||
while (_rtsIconPool.Count <= index)
|
||||
{
|
||||
RawImage icon;
|
||||
if (RtsIconPrototype != null)
|
||||
{
|
||||
icon = Instantiate(RtsIconPrototype, RtsIconRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
var go = new GameObject("RTS Map Icon", typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage));
|
||||
go.transform.SetParent(RtsIconRoot, false);
|
||||
icon = go.GetComponent<RawImage>();
|
||||
icon.texture = Texture2D.whiteTexture;
|
||||
icon.raycastTarget = false;
|
||||
}
|
||||
|
||||
_rtsIconPool.Add(icon);
|
||||
}
|
||||
|
||||
return _rtsIconPool[index];
|
||||
}
|
||||
|
||||
private void ApplyRtsIcon(RawImage icon, AetheriaRuntimeRtsViewportObject obj)
|
||||
{
|
||||
if (icon == null || obj == null)
|
||||
return;
|
||||
|
||||
icon.gameObject.SetActive(true);
|
||||
if (AssetCatalog != null && AssetCatalog.TryResolveTexture(obj.IconAsset, out var texture))
|
||||
icon.texture = texture;
|
||||
icon.color = ResolveIconColor(obj);
|
||||
var rectTransform = icon.rectTransform;
|
||||
var pixelSize = Mathf.Max(4f, IconSize * (obj.Controlled ? 1.25f : 1f));
|
||||
rectTransform.anchorMin = rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
rectTransform.pivot = new Vector2(0.5f, 0.5f);
|
||||
rectTransform.sizeDelta = new Vector2(pixelSize, pixelSize);
|
||||
rectTransform.anchoredPosition = WorldToMapPosition(obj.X, obj.Y);
|
||||
rectTransform.localRotation = Quaternion.Euler(
|
||||
0,
|
||||
0,
|
||||
Mathf.Atan2((float)obj.DirectionY, (float)obj.DirectionX) * Mathf.Rad2Deg - 90f);
|
||||
}
|
||||
|
||||
private Vector2 WorldToMapPosition(double worldX, double worldY)
|
||||
{
|
||||
var viewport = _objectsViewport?.Viewport ?? ResolveViewportBounds();
|
||||
var minX = Math.Min(viewport.MinX, viewport.MaxX);
|
||||
var maxX = Math.Max(viewport.MinX, viewport.MaxX);
|
||||
var minY = Math.Min(viewport.MinY, viewport.MaxY);
|
||||
var maxY = Math.Max(viewport.MinY, viewport.MaxY);
|
||||
var width = Math.Max(0.0001, maxX - minX);
|
||||
var height = Math.Max(0.0001, maxY - minY);
|
||||
var rootRect = RtsIconRoot != null ? RtsIconRoot.rect : new Rect(0, 0, _size.x, _size.y);
|
||||
var u = (float)((worldX - minX) / width);
|
||||
var v = (float)((worldY - minY) / height);
|
||||
return new Vector2(
|
||||
(u - 0.5f) * rootRect.width,
|
||||
(v - 0.5f) * rootRect.height);
|
||||
}
|
||||
|
||||
private static Color ResolveIconColor(AetheriaRuntimeRtsViewportObject obj)
|
||||
{
|
||||
var color = obj.Controlled
|
||||
? new Color(0.3f, 0.9f, 1.0f, 1.0f)
|
||||
: Color.HSVToRGB(frac((obj.FactionKey ?? obj.Kind ?? "").GetHashCode() * 0.0137f), 0.55f, 0.95f);
|
||||
color.a = Mathf.Clamp01(Mathf.Max(0.25f, (float)obj.Visibility));
|
||||
return color;
|
||||
}
|
||||
|
||||
private void EnsureRtsIconRoot()
|
||||
{
|
||||
if (RtsIconRoot != null)
|
||||
return;
|
||||
|
||||
var parent = GravityDisplay != null
|
||||
? GravityDisplay.transform.parent
|
||||
: transform;
|
||||
var go = new GameObject("RTS Command Icons", typeof(RectTransform));
|
||||
go.transform.SetParent(parent, false);
|
||||
RtsIconRoot = go.GetComponent<RectTransform>();
|
||||
RtsIconRoot.anchorMin = Vector2.zero;
|
||||
RtsIconRoot.anchorMax = Vector2.one;
|
||||
RtsIconRoot.offsetMin = Vector2.zero;
|
||||
RtsIconRoot.offsetMax = Vector2.zero;
|
||||
RtsIconRoot.SetAsLastSibling();
|
||||
}
|
||||
|
||||
private void SetRtsIconsActive(bool active)
|
||||
{
|
||||
if (RtsIconRoot != null)
|
||||
RtsIconRoot.gameObject.SetActive(active);
|
||||
}
|
||||
|
||||
private AetheriaRuntimeRtsViewportBounds ResolveViewportBounds()
|
||||
{
|
||||
var screenHeight = _size.y <= 0 ? Math.Max(1, Screen.height) : _size.y;
|
||||
|
|
|
|||
Loading…
Reference in a new issue