planet rendering

This commit is contained in:
2024-12-15 16:51:09 -06:00
parent 5a62541e21
commit b9a1347fae
8 changed files with 328 additions and 130 deletions

View File

@@ -11,6 +11,8 @@ GameObject:
- component: {fileID: 7161697913015591788}
- component: {fileID: -2170283451010205844}
- component: {fileID: -5258542714815234591}
- component: {fileID: -945589377389130640}
- component: {fileID: 2580485966366843203}
m_Layer: 0
m_Name: BasePlanet
m_TagString: Untagged
@@ -45,10 +47,11 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 5e5a2958b00708d4bacd5703ef7b2b50, type: 3}
m_Name:
m_EditorClassIdentifier:
Size: 95
Size: 151
Bulbs: 1
edgeColor: {r: 1, g: 1, b: 1, a: 1}
edgeWidth: 0.0369
edgeColor: {r: 0.4811321, g: 0.4811321, b: 0.4811321, a: 1}
fillColor: {r: 0.1509434, g: 0.1509434, b: 0.1509434, a: 1}
edgeWidth: 0.0466
--- !u!120 &-5258542714815234591
LineRenderer:
serializedVersion: 2
@@ -92,104 +95,56 @@ LineRenderer:
m_SortingLayer: 0
m_SortingOrder: 0
m_Positions:
- {x: 0, y: 0.95, z: 0}
- {x: 0.06278606, y: 0.94792295, z: 0}
- {x: 0.12529755, y: 0.9417008, z: 0}
- {x: 0.18726118, y: 0.93136096, z: 0}
- {x: 0.24840592, y: 0.91694844, z: 0}
- {x: 0.3084645, y: 0.8985264, z: 0}
- {x: 0.3671742, y: 0.8761752, z: 0}
- {x: 0.42427838, y: 0.8499929, z: 0}
- {x: 0.47952724, y: 0.8200937, z: 0}
- {x: 0.53267926, y: 0.7866084, z: 0}
- {x: 0.58350205, y: 0.7496835, z: 0}
- {x: 0.63177335, y: 0.7094804, z: 0}
- {x: 0.67728204, y: 0.66617495, z: 0}
- {x: 0.71982914, y: 0.6199565, z: 0}
- {x: 0.7592286, y: 0.57102716, z: 0}
- {x: 0.7953082, y: 0.5196008, z: 0}
- {x: 0.82791, y: 0.4659024, z: 0}
- {x: 0.8568917, y: 0.41016662, z: 0}
- {x: 0.8821263, y: 0.3526374, z: 0}
- {x: 0.9035037, y: 0.29356614, z: 0}
- {x: 0.92093027, y: 0.23321122, z: 0}
- {x: 0.9343298, y: 0.17183656, z: 0}
- {x: 0.9436438, y: 0.109710395, z: 0}
- {x: 0.94883144, y: 0.047104605, z: 0}
- {x: 0.94987017, y: -0.015707277, z: 0}
- {x: 0.94675523, y: -0.07845037, z: 0}
- {x: 0.93950045, y: -0.14085041, z: 0}
- {x: 0.9281375, y: -0.20263465, z: 0}
- {x: 0.912716, y: -0.26353273, z: 0}
- {x: 0.8933034, y: -0.32327855, z: 0}
- {x: 0.8699847, y: -0.38161063, z: 0}
- {x: 0.8428617, y: -0.43827406, z: 0}
- {x: 0.81205314, y: -0.493021, z: 0}
- {x: 0.77769357, y: -0.5456123, z: 0}
- {x: 0.7399334, y: -0.59581757, z: 0}
- {x: 0.6989377, y: -0.6434175, z: 0}
- {x: 0.65488577, y: -0.6882039, z: 0}
- {x: 0.6079702, y: -0.72998095, z: 0}
- {x: 0.5583959, y: -0.7685662, z: 0}
- {x: 0.50638014, y: -0.8037905, z: 0}
- {x: 0.45215005, y: -0.83550006, z: 0}
- {x: 0.39594284, y: -0.86355615, z: 0}
- {x: 0.33800426, y: -0.8878362, z: 0}
- {x: 0.27858746, y: -0.908234, z: 0}
- {x: 0.2179527, y: -0.92466027, z: 0}
- {x: 0.15636489, y: -0.93704325, z: 0}
- {x: 0.09409333, y: -0.9453288, z: 0}
- {x: 0.03141032, y: -0.9494806, z: 0}
- {x: -0.031410262, y: -0.9494806, z: 0}
- {x: -0.09409327, y: -0.9453288, z: 0}
- {x: -0.15636483, y: -0.93704325, z: 0}
- {x: -0.21795264, y: -0.92466027, z: 0}
- {x: -0.2785874, y: -0.908234, z: 0}
- {x: -0.3380042, y: -0.8878362, z: 0}
- {x: -0.39594278, y: -0.8635562, z: 0}
- {x: -0.45215, y: -0.83550006, z: 0}
- {x: -0.5063801, y: -0.80379057, z: 0}
- {x: -0.55839586, y: -0.7685662, z: 0}
- {x: -0.6079701, y: -0.729981, z: 0}
- {x: -0.6548857, y: -0.68820393, z: 0}
- {x: -0.6989377, y: -0.64341754, z: 0}
- {x: -0.7399333, y: -0.59581757, z: 0}
- {x: -0.7776935, y: -0.54561234, z: 0}
- {x: -0.81205297, y: -0.49302122, z: 0}
- {x: -0.8428616, y: -0.43827432, z: 0}
- {x: -0.86998475, y: -0.38161048, z: 0}
- {x: -0.89330345, y: -0.3232784, z: 0}
- {x: -0.912716, y: -0.26353267, z: 0}
- {x: -0.9281375, y: -0.2026346, z: 0}
- {x: -0.93950045, y: -0.14085047, z: 0}
- {x: -0.94675523, y: -0.07845042, z: 0}
- {x: -0.94987017, y: -0.015707338, z: 0}
- {x: -0.9488315, y: 0.04710443, z: 0}
- {x: -0.9436438, y: 0.109710224, z: 0}
- {x: -0.93432987, y: 0.17183627, z: 0}
- {x: -0.9209302, y: 0.23321138, z: 0}
- {x: -0.90350366, y: 0.29356626, z: 0}
- {x: -0.8821263, y: 0.35263747, z: 0}
- {x: -0.85689163, y: 0.41016665, z: 0}
- {x: -0.82791, y: 0.46590233, z: 0}
- {x: -0.7953082, y: 0.51960075, z: 0}
- {x: -0.75922865, y: 0.57102704, z: 0}
- {x: -0.71982926, y: 0.6199564, z: 0}
- {x: -0.67728215, y: 0.6661748, z: 0}
- {x: -0.63177353, y: 0.7094802, z: 0}
- {x: -0.58350194, y: 0.7496836, z: 0}
- {x: -0.5326792, y: 0.78660846, z: 0}
- {x: -0.47952718, y: 0.8200937, z: 0}
- {x: -0.42427835, y: 0.84999293, z: 0}
- {x: -0.3671742, y: 0.8761752, z: 0}
- {x: -0.30846456, y: 0.8985264, z: 0}
- {x: -0.24840604, y: 0.91694844, z: 0}
- {x: -0.18726131, y: 0.93136096, z: 0}
- {x: -0.12529776, y: 0.9417008, z: 0}
- {x: -0.062786296, y: 0.9479229, z: 0}
- {x: 1.51, y: 0, z: 0}
- {x: 1.496527, y: 0.20126332, z: 0}
- {x: 1.4563484, y: 0.39893508, z: 0}
- {x: 1.3901813, y: 0.5894878, z: 0}
- {x: 1.2992064, y: 0.7695212, z: 0}
- {x: 1.185047, y: 0.93582237, z: 0}
- {x: 1.0497406, y: 1.0854237, z: 0}
- {x: 0.89570135, y: 1.2156558, z: 0}
- {x: 0.7256784, y: 1.3241944, z: 0}
- {x: 0.5427058, y: 1.4091028, z: 0}
- {x: 0.3500483, y: 1.4688656, z: 0}
- {x: 0.15114443, y: 1.5024165, z: 0}
- {x: -0.050456624, y: 1.5091567, z: 0}
- {x: -0.25115746, y: 1.488966, z: 0}
- {x: -0.4473762, y: 1.4422047, z: 0}
- {x: -0.6356115, y: 1.3697072, z: 0}
- {x: -0.8125045, y: 1.2727673, z: 0}
- {x: -0.9748982, y: 1.1531147, z: 0}
- {x: -1.1198947, y: 1.0128849, z: 0}
- {x: -1.2449068, y: 0.85458, z: 0}
- {x: -1.3477036, y: 0.681025, z: 0}
- {x: -1.4264503, y: 0.49531755, z: 0}
- {x: -1.4797422, y: 0.3007707, z: 0}
- {x: -1.506628, y: 0.100856625, z: 0}
- {x: -1.5066279, y: -0.10085689, z: 0}
- {x: -1.4797422, y: -0.30077097, z: 0}
- {x: -1.4264503, y: -0.49531776, z: 0}
- {x: -1.3477035, y: -0.6810253, z: 0}
- {x: -1.2449067, y: -0.8545802, z: 0}
- {x: -1.1198945, y: -1.0128851, z: 0}
- {x: -0.97489804, y: -1.1531148, z: 0}
- {x: -0.81250393, y: -1.2727677, z: 0}
- {x: -0.6356113, y: -1.3697073, z: 0}
- {x: -0.44737607, y: -1.4422047, z: 0}
- {x: -0.25115684, y: -1.4889662, z: 0}
- {x: -0.05045636, y: -1.5091567, z: 0}
- {x: 0.15114452, y: -1.5024165, z: 0}
- {x: 0.35004893, y: -1.4688655, z: 0}
- {x: 0.54270595, y: -1.4091027, z: 0}
- {x: 0.72567844, y: -1.3241943, z: 0}
- {x: 0.89570177, y: -1.2156554, z: 0}
- {x: 1.0497408, y: -1.0854236, z: 0}
- {x: 1.185047, y: -0.93582237, z: 0}
- {x: 1.2992066, y: -0.7695207, z: 0}
- {x: 1.3901814, y: -0.58948755, z: 0}
- {x: 1.4563484, y: -0.39893502, z: 0}
- {x: 1.4965271, y: -0.2012628, z: 0}
m_Parameters:
serializedVersion: 3
widthMultiplier: 0.0369
widthMultiplier: 0.0466
widthCurve:
serializedVersion: 2
m_Curve:
@@ -207,8 +162,8 @@ LineRenderer:
m_RotationOrder: 4
colorGradient:
serializedVersion: 2
key0: {r: 1, g: 1, b: 1, a: 1}
key1: {r: 1, g: 1, b: 1, a: 1}
key0: {r: 0.48235294, g: 0.48235294, b: 0.48235294, a: 1}
key1: {r: 0.48235294, g: 0.48235294, b: 0.48235294, a: 1}
key2: {r: 0, g: 0, b: 0, a: 0}
key3: {r: 0, g: 0, b: 0, a: 0}
key4: {r: 0, g: 0, b: 0, a: 0}
@@ -246,3 +201,53 @@ LineRenderer:
m_UseWorldSpace: 1
m_Loop: 1
m_ApplyActiveColorSpace: 1
--- !u!33 &-945589377389130640
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7154824257338098917}
m_Mesh: {fileID: 0}
--- !u!23 &2580485966366843203
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7154824257338098917}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 1
m_DynamicOccludee: 0
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 9435572d88e255e4c8dccdfa581d9598, type: 2}
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}

View File

@@ -7,10 +7,29 @@ public class Network : MonoBehaviour
private List<Planet> _planets;
public Planet planetPrefab;
public void EnsureReady()
{
if (_planets == null)
{
_planets = new List<Planet>(FindObjectsOfType<Planet>());
}
else
{
_planets.Clear();
_planets.AddRange(FindObjectsOfType<Planet>());
}
}
public void Awake()
{
EnsureReady();
}
public void AddPlanet()
{
EnsureReady();
var planet = Instantiate(planetPrefab);
planet.GenerateLine();
planet.Render();
planet.name = $"Planet {_planets.Count + 1}";
planet.transform.parent = transform;
_planets.Add(planet);

View File

@@ -1,11 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Planet : MonoBehaviour
{
private PolygonCollider2D _collider;
private MeshFilter _meshFilter;
private LineRenderer _lineRenderer;
private Network _network;
@@ -14,11 +13,11 @@ public class Planet : MonoBehaviour
[HideInInspector] public float Size; // 1.0 -
[HideInInspector] public int Bulbs; // 0 - 5+
public Color edgeColor = Color.white;
public Color fillColor = Color.white;
[HideInInspector] public float edgeWidth = 0.2f;
void Awake()
{
_collider = gameObject.GetComponent<PolygonCollider2D>();
_lineRenderer = gameObject.GetComponent<LineRenderer>();
_network = FindObjectOfType<Network>();
}
@@ -46,8 +45,9 @@ public class Planet : MonoBehaviour
}
}
public void GenerateLine()
public void Render()
{
_meshFilter = gameObject.GetComponent<MeshFilter>();
_lineRenderer = gameObject.GetComponent<LineRenderer>();
_lineRenderer.widthMultiplier = edgeWidth;
@@ -57,30 +57,42 @@ public class Planet : MonoBehaviour
_lineRenderer.endColor = edgeColor;
_lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
// Calculate points for circle
int pointCount = Math.Max((int)Size, 16);
_lineRenderer.positionCount = pointCount;
var points = new Vector3[pointCount];
var radius = Size / 100f;
const float segmentOffset = 40f;
const float segmentMultiplier = 50f;
var numSegments = (int)(radius * segmentMultiplier + segmentOffset);
// Generate points
for (var i = 0; i < pointCount; i++)
// Create an array of points around a circle
var circleVertices = Enumerable.Range(0, numSegments)
.Select(i =>
{
var theta = 2 * Mathf.PI * i / numSegments;
return new Vector2(Mathf.Cos(theta), Mathf.Sin(theta)) * radius;
})
.ToArray();
// Find all the triangles in the shape
var triangles = new Triangulator(circleVertices).Triangulate();
// Assign each vertex the fill color
var colors = Enumerable.Repeat(fillColor, circleVertices.Length).ToArray();
var mesh = new Mesh
{
var rad = Mathf.Deg2Rad * (i * 360f / pointCount);
points[i] = new Vector3(Mathf.Sin(rad) * Size / 100f, Mathf.Cos(rad) * Size / 100f, 0);
}
name = "Circle",
vertices = circleVertices.ToVector3(),
triangles = triangles,
colors = colors
};
// Add points to LineRenderer
_lineRenderer.SetPositions(points);
Debug.Log($"{triangles.Length} triangles");
// Use the line-renderer's Vector3's to create vector2 collider path
var path = new Vector2[_lineRenderer.positionCount + 1];
for (var i = 0; i < pointCount; i++)
{
// Convert Vector3 to Vector2
path[i] = points[i];
}
mesh.RecalculateNormals();
mesh.RecalculateBounds();
mesh.RecalculateTangents();
path[_lineRenderer.positionCount] = path[0];
// _collider.SetPath(0, path);
_meshFilter.mesh = mesh;
_lineRenderer.positionCount = mesh.vertices.Length;
_lineRenderer.SetPositions(mesh.vertices);
}
}

View File

@@ -22,12 +22,14 @@ public class PlanetEditor : Editor
return;
}
var changed = false;
// Check if size changed
var newSize = EditorGUILayout.Slider("Size", planet.Size, 1f, 300f);
if (newSize != planet.Size)
{
planet.Size = newSize;
planet.GenerateLine();
changed = true;
}
// Check if bulbs changed
@@ -35,7 +37,7 @@ public class PlanetEditor : Editor
if (newBulbs != planet.Bulbs)
{
planet.Bulbs = newBulbs;
planet.GenerateLine();
changed = true;
}
// Check if edge width changed
@@ -43,9 +45,11 @@ public class PlanetEditor : Editor
if (newEdgeWidth != planet.edgeWidth)
{
planet.edgeWidth = newEdgeWidth;
planet.GenerateLine();
changed = true;
}
if (changed) planet.Render();
DrawDefaultInspector();
}
}

127
Assets/Triangular.cs Normal file
View File

@@ -0,0 +1,127 @@
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// This script can be used to split a 2D polygon into triangles.
/// The algorithm supports concave polygons, but not polygons with holes,
/// or multiple polygons at once.
/// Taken from <see cref="http://wiki.unity3d.com/index.php?title=Triangulator"/>
/// </summary>
public class Triangulator
{
private readonly List<Vector2> _mPoints;
public Triangulator(IEnumerable<Vector2> points)
{
_mPoints = new List<Vector2>(points);
}
public int[] Triangulate()
{
var indices = new List<int>();
var n = _mPoints.Count;
if (n < 3)
return indices.ToArray();
var V = new int[n];
if (Area() > 0)
{
for (var v = 0; v < n; v++)
V[v] = v;
}
else
{
for (var v = 0; v < n; v++)
V[v] = n - 1 - v;
}
var nv = n;
var count = 2 * nv;
for (int m = 0, v = nv - 1; nv > 2;)
{
if (count-- <= 0)
return indices.ToArray();
var u = v;
if (nv <= u)
u = 0;
v = u + 1;
if (nv <= v)
v = 0;
var w = v + 1;
if (nv <= w)
w = 0;
if (Snip(u, v, w, nv, V))
{
int a, b, c, s, t;
a = V[u];
b = V[v];
c = V[w];
indices.Add(a);
indices.Add(b);
indices.Add(c);
m++;
for (s = v, t = v + 1; t < nv; s++, t++)
V[s] = V[t];
nv--;
count = 2 * nv;
}
}
indices.Reverse();
return indices.ToArray();
}
private float Area()
{
var n = _mPoints.Count;
var A = 0.0f;
for (int p = n - 1, q = 0; q < n; p = q++)
{
var pval = _mPoints[p];
var qval = _mPoints[q];
A += pval.x * qval.y - qval.x * pval.y;
}
return A * 0.5f;
}
private bool Snip(int u, int v, int w, int n, int[] V)
{
int p;
var A = _mPoints[V[u]];
var B = _mPoints[V[v]];
var C = _mPoints[V[w]];
if (Mathf.Epsilon > (B.x - A.x) * (C.y - A.y) - (B.y - A.y) * (C.x - A.x))
return false;
for (p = 0; p < n; p++)
{
if (p == u || p == v || p == w)
continue;
var P = _mPoints[V[p]];
if (InsideTriangle(A, B, C, P))
return false;
}
return true;
}
private static bool InsideTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P)
{
float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
float cCROSSap, bCROSScp, aCROSSbp;
ax = C.x - B.x; ay = C.y - B.y;
bx = A.x - C.x; by = A.y - C.y;
cx = B.x - A.x; cy = B.y - A.y;
apx = P.x - A.x; apy = P.y - A.y;
bpx = P.x - B.x; bpy = P.y - B.y;
cpx = P.x - C.x; cpy = P.y - C.y;
aCROSSbp = ax * bpy - ay * bpx;
cCROSSap = cx * apy - cy * apx;
bCROSScp = bx * cpy - by * cpx;
return aCROSSbp >= 0.0f && bCROSScp >= 0.0f && cCROSSap >= 0.0f;
}
}

11
Assets/Triangular.cs.meta Normal file
View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26c937dd0f280c547b25a0164401a13f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/Utility.cs Normal file
View File

@@ -0,0 +1,9 @@
using UnityEngine;
public static class Utility
{
public static Vector3[] ToVector3(this Vector2[] vectors)
{
return System.Array.ConvertAll<Vector2, Vector3>(vectors, static v => v);
}
}

11
Assets/Utility.cs.meta Normal file
View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf652e25d11ff3c49b711666bb816db3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: