Skip to content

Commit

Permalink
moved camera extents into own class to not cause a conflict or depend…
Browse files Browse the repository at this point in the history
…ency with legacy nl3d core
  • Loading branch information
sambaas committed Jan 24, 2024
1 parent bf4ba37 commit 89fd6eb
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 5 deletions.
6 changes: 3 additions & 3 deletions Runtime/Scripts/Camera2DFrustum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
*/

using Netherlands3D.Coordinates;
using Netherlands3D.Core;
using UnityEngine;

namespace Netherlands3D.Minimap
Expand All @@ -40,8 +39,9 @@ void Update()
private void DrawCameraFrustumOnMap()
{
//Get corners
Camera.main.GetRDExtent();
var cameraCorners = Camera.main.GetWorldSpaceCorners();
var mainCamera = Camera.main;
CameraExtents.GetRDExtent(mainCamera);
var cameraCorners = CameraExtents.GetWorldSpaceCorners(mainCamera);

if (cameraCorners != null)
{
Expand Down
128 changes: 128 additions & 0 deletions Runtime/Scripts/CameraExtents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using UnityEngine;
using System.Collections;
using Netherlands3D.Coordinates;

namespace Netherlands3D.Minimap
{
public static class CameraExtents
{
public static Vector3[] corners = new Vector3[4];

private static Vector3 unityMin;
private static Vector3 unityMax;

private static Vector2 topLeft = new Vector2(0, 1);
private static Vector2 topRight = new Vector2(1, 1);
private static Vector2 bottomRight = new Vector2(1, 0);
private static Vector2 bottomLeft = new Vector2(0, 0);

private static Plane[] cameraFrustumPlanes = new Plane[6]
{
new Plane(), //Left
new Plane(), //Right
new Plane(), //Down
new Plane(), //Up
new Plane(), //Near
new Plane(), //Far
};

public static Extent GetExtent(Camera camera, float maximumViewDistance = 0)
{
if (maximumViewDistance == 0) maximumViewDistance = camera.farClipPlane;
CalculateCornerExtents(camera, maximumViewDistance);

// Area that should be loaded
var extent = new Extent(unityMin.x, unityMin.z, unityMax.x, unityMax.z);

return extent;
}

public static Extent GetRDExtent(Camera camera, float maximumViewDistance = 0)
{
if (maximumViewDistance == 0) maximumViewDistance = camera.farClipPlane;
CalculateCornerExtents(camera, maximumViewDistance);

// Convert min and max to WGS84 coordinates
var rdMin = CoordinateConverter.UnitytoRD(unityMin);
var rdMax = CoordinateConverter.UnitytoRD(unityMax);

// Area that should be loaded
var extent = new Extent(rdMin.x, rdMin.y, rdMax.x, rdMax.y);

return extent;
}

private static void CalculateCornerExtents(Camera camera, float maximumViewDistance)
{
// Determine what world coordinates are in the corners of our view
corners[0] = GetCornerPoint(camera, topLeft, maximumViewDistance);
corners[1] = GetCornerPoint(camera, topRight, maximumViewDistance);
corners[2] = GetCornerPoint(camera, bottomRight, maximumViewDistance);
corners[3] = GetCornerPoint(camera, bottomLeft, maximumViewDistance);

// Determine the min and max X- en Z-value of the visible coordinates
unityMax = new Vector3(-float.MaxValue, -float.MaxValue, -float.MaxValue);
unityMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
for (int i = 0; i < 4; i++)
{
unityMin.x = Mathf.Min(unityMin.x, corners[i].x);
unityMin.z = Mathf.Min(unityMin.z, corners[i].z);
unityMax.x = Mathf.Max(unityMax.x, corners[i].x);
unityMax.z = Mathf.Max(unityMax.z, corners[i].z);
}
}

private static Vector3 GetCornerPoint(Camera camera, Vector2 screenPosition, float maximumViewDistance)
{
var output = new Vector3();

var topScreenPointFar = Camera.main.ViewportToWorldPoint(new Vector3(screenPosition.x, screenPosition.y, 10000));
var topScreenPointNear = Camera.main.ViewportToWorldPoint(new Vector3(screenPosition.x, screenPosition.y, 10));

// Calculate direction vector
Vector3 direction = topScreenPointNear - topScreenPointFar;
float factor; //factor waarmee de Richtingvector vermenigvuldigd moet worden om op het maaiveld te stoppen
if (direction.y < 0) //wanneer de Richtingvector omhooggaat deze factor op 1 instellen
{
factor = 1;
}
else
{
factor = ((topScreenPointNear.y) / direction.y); //factor bepalen t.o.v. maaiveld (aanname maaiveld op 0 NAP = ca 40 Unityeenheden in Y-richting)
}

// Determine the X, Y, en Z location where the viewline ends
output.x = topScreenPointNear.x - Mathf.Clamp((factor * direction.x), -1 * maximumViewDistance, maximumViewDistance);
output.y = topScreenPointNear.y - Mathf.Clamp((factor * direction.y), -1 * maximumViewDistance, maximumViewDistance);
output.z = topScreenPointNear.z - Mathf.Clamp((factor * direction.z), -1 * maximumViewDistance, maximumViewDistance);

return output;
}

public static Vector3[] GetWorldSpaceCorners(Camera camera)
{
return corners;
}

/// <summary>
/// Get the position of a screen point in world coordinates ( on a plane )
/// </summary>
/// <param name="screenPoint">The point in screenpoint coordinates</param>
/// <returns></returns>
public static Vector3 GetCoordinateInWorld(Camera camera, Vector3 screenPoint, Plane worldPlane, float maxSelectionDistanceFromCamera = Mathf.Infinity)
{
var screenRay = camera.ScreenPointToRay(screenPoint);

worldPlane.Raycast(screenRay, out float distance);
var samplePoint = screenRay.GetPoint(Mathf.Min(maxSelectionDistanceFromCamera, distance));

return samplePoint;
}

public static bool InView(this Camera camera, Bounds bounds)
{
GeometryUtility.CalculateFrustumPlanes(camera, cameraFrustumPlanes);
return GeometryUtility.TestPlanesAABB(cameraFrustumPlanes, bounds);
}
}
}
11 changes: 11 additions & 0 deletions Runtime/Scripts/CameraExtents.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 64 additions & 0 deletions Runtime/Scripts/Extent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;

namespace Netherlands3D.Minimap
{
public struct Extent
{
private readonly double _minX;
private readonly double _minY;
private readonly double _maxX;
private readonly double _maxY;

public Extent(double minX, double minY, double maxX, double maxY) : this()
{
_minX = minX;
_minY = minY;
_maxX = maxX;
_maxY = maxY;

if (minX > maxX || minY > maxY)
{
throw new ArgumentException("min should be smaller than max");
}
}

public double MinX
{
get { return _minX; }
}

public double MinY
{
get { return _minY; }
}

public double MaxX
{
get { return _maxX; }
}

public double MaxY
{
get { return _maxY; }
}

public double CenterX => (MinX + MaxX) / 2.0;
public double CenterY => (MinY + MaxY) / 2.0;
public double Width => MaxX - MinX;
public double Height => MaxY - MinY;
public double Area => Width * Height;

public override bool Equals(object obj)
{
if (!(obj is Extent extent))
return false;

return this.CenterX == extent.CenterX && this.MinX == extent.MinX && this.MinY == extent.MinY && this.MaxX == extent.MaxX && this.MaxY == extent.MaxY;
}

public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
11 changes: 11 additions & 0 deletions Runtime/Scripts/Extent.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Runtime/Scripts/TileMatrixSet.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Netherlands3D.Core;
using System.Collections;
using System.Collections.Generic;
using Netherlands3D.Coordinates;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "Netherlands3D.Minimap",
"rootNamespace": "Netherlands3D.Minimap",
"references": [
"GUID:9ca88277166fea644a31588b4f943acc",
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:19c45768ddcd67943afbf0cb4e4ff0b3",
"GUID:342dff139556fc14d832ad802c9dafd2"
Expand Down

0 comments on commit 89fd6eb

Please sign in to comment.