OldBlueWater/BlueWater/Assets/RayFire/Scripts/Classes/Shatter/RFHexagon.cs
2023-08-22 14:31:24 +09:00

168 lines
5.6 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
namespace RayFire
{
[Serializable]
public class RFHexagon
{
public PlaneType plane;
public int row;
public int col;
public float size;
public float div;
public bool rest;
public bool enable;
public bool noPc;
public List<Vector3> pc;
public List<Vector3> pcBndIn;
public List<Vector3> pcBndOut;
Matrix4x4 matrix;
/// /////////////////////////////////////////////////////////
/// Constructor
/// /////////////////////////////////////////////////////////
public RFHexagon()
{
plane = PlaneType.XZ;
row = 20;
col = 20;
size = 0.5f;
div = 0f;
rest = true;
enable = true;
}
public RFHexagon(RFHexagon src)
{
plane = src.plane;
row = src.row;
col = src.col;
size = src.size;
div = src.div;
rest = src.rest;
enable = src.enable;
}
/// /////////////////////////////////////////////////////////
/// Static
/// /////////////////////////////////////////////////////////
// Get final point cloud for hexgrid fragmentation
public static List<Vector3> GetHexPointCLoud (RFHexagon hexagon, Transform tm, Vector3 centerPos, Quaternion centerDirection, int seed, Bounds bound)
{
// Generate hex grid point cloud
SetHexOutputCloud (hexagon);
// Matrix multiply
Quaternion quat = centerDirection * tm.rotation;
if (hexagon.plane == PlaneType.XY)
quat = quat * Quaternion.Euler(90, 0, 0);
if (hexagon.plane == PlaneType.YZ)
quat = quat * Quaternion.Euler(0, 0, 90);
hexagon.matrix = Matrix4x4.TRS(centerPos, quat.normalized, Vector3.one);
for (int i = 0; i < hexagon.pc.Count; i++)
hexagon.pc[i] = hexagon.matrix.MultiplyPoint (hexagon.pc[i]);;
// Set points in bound
SetCustomBoundPoints (hexagon, bound);
// Stop if no points
hexagon.noPc = false;
if (hexagon.pcBndIn.Count <= 1)
hexagon.noPc = true;
return hexagon.pc; // TODO
}
// Generate hex grid point cloud
static void SetHexOutputCloud (RFHexagon hexagon)
{
if (hexagon.pc == null)
hexagon.pc = new List<Vector3>();
else
hexagon.pc.Clear();
// Set grid size
int rowP = hexagon.row / 2;
int rowM = hexagon.row - rowP;
int colP = hexagon.col / 2;
int colM = hexagon.col - colP;
float z, h, x;
bool offset = true;
for (int r = -rowM; r < rowP; r++)
{
// Set row coordinate for row hex centers
z = 1.5f * hexagon.size * r;
// Generate row hexes by offset
offset = !offset;
for (int c = -colM; c < colP; c++)
{
h = (float)(hexagon.size * Math.Sqrt (3));
x = h * c;
if (offset == true)
x += h / 2f;
// Collect
hexagon.pc.Add (new Vector3 (x, 0, z));
}
}
// Divergence
SetHexDivergence (hexagon);
}
// Divergence
static void SetHexDivergence(RFHexagon hexagon)
{
if (hexagon.div > 0)
{
// Set variation values
float varX = hexagon.div / 2f;
float varY = hexagon.div / 2f;
float varZ = hexagon.div / 2f;
// Restrict to plane
if (hexagon.rest == true)
{
if (hexagon.plane == PlaneType.XZ)
varY = 0;
else if (hexagon.plane == PlaneType.XY)
varZ = 0;
else if (hexagon.plane == PlaneType.YZ)
varX = 0;
}
// Random offset
Random.InitState (0);
for (int i = 0; i < hexagon.pc.Count; i++)
hexagon.pc[i] += new Vector3(Random.Range (-varX, varX), Random.Range (-varY, varY), Random.Range (-varZ, varZ));
}
}
// Filter world points by bound intersection
static void SetCustomBoundPoints(RFHexagon hexagon, Bounds bound)
{
// Set outbound list
if (hexagon.pcBndOut == null)
hexagon.pcBndOut = new List<Vector3>();
else hexagon.pcBndOut.Clear();
if (hexagon.pcBndIn == null)
hexagon.pcBndIn = new List<Vector3>();
else hexagon.pcBndIn.Clear();
// Filter points byu bound
for (int i = hexagon.pc.Count - 1; i >= 0; i--)
if (bound.Contains(hexagon.pc[i]) == false)
hexagon.pcBndOut.Add (hexagon.pc[i]);
else
hexagon.pcBndIn.Add (hexagon.pc[i]);
}
}
}