You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
8.0 KiB

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UltraCombos
{
public class Utilities
{
const float TWO_PI = Mathf.PI * 2.0f;
public static float[] GetShuffleSeeds(int num)
{
List<float> sources = new List<float>();
for (uint i = 0; i < num; i++)
sources.Add((float)i / num);
var rnd = new System.Random();
return sources.OrderBy(item => rnd.Next()).ToArray();
}
public static Mesh[] GetUVIndexPolygons(int maxParticles, int side, float radius, float randomRadius = 0.0f, float startAngle = 0)
{
#if UNITY_2017_3_OR_NEWER
int num_meshes = 1;
#else
int limit = 65000;
int num_vertices = maxParticles * side;
int num_meshes = (num_vertices + limit - 1) / limit;
#endif
int ptc_per_mesh = maxParticles / num_meshes;
Mesh[] meshes = new Mesh[num_meshes];
float r_mul = Mathf.Clamp01(randomRadius);
float r_max = radius * (1.0f + r_mul);
float r_min = radius * (1.0f - r_mul);
for (int i = 0; i < num_meshes; i++)
{
var vertices = new List<Vector3>();
var uvs = new List<Vector4>();
var normals = new List<Vector3>();
var indices = new List<int>();
for (int j = 0; j < ptc_per_mesh; j++)
{
int index = i * ptc_per_mesh + j;
float delta_a = TWO_PI / side;
for (uint k = 0; k < side; k++)
{
float a = delta_a * k + Mathf.PI / 4;
float x = Mathf.Cos(a);
float y = Mathf.Sin(a);
float r = Random.Range(r_min, r_max);
vertices.Add(new Vector3(x * r, y * r, 0));
uvs.Add(new Vector4(x * 0.5f + 0.5f, y * 0.5f + 0.5f, index, k));
normals.Add(new Vector3(0, 0, 1));
}
for (int k = 0; k < side - 2; k++)
{
indices.Add(j * side + 0);
indices.Add(j * side + k + 1);
indices.Add(j * side + k + 2);
}
}
meshes[i] = new Mesh();
#if UNITY_2017_3_OR_NEWER
meshes[i].indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
#endif
meshes[i].SetVertices(vertices);
meshes[i].SetUVs(0, uvs);
meshes[i].SetNormals(normals);
meshes[i].SetIndices(indices.ToArray(), MeshTopology.Triangles, 0);
meshes[i].bounds = new Bounds(Vector3.zero, Vector3.one * 100.0f);
}
return meshes;
}
public static float GetTimeValue()
{
uint interval = 100000;
uint milli_time = (uint)(Time.time * 1000);
float value = milli_time % interval / (float)interval;
return Mathf.Sin(value * TWO_PI) * 0.5f + 0.5f; // continuous sin value
}
public static void Release(ref ComputeBuffer buffer)
{
if (buffer != null)
buffer.Release();
buffer = null;
}
static List<string> skip_camera_names = null;
public static bool SkipCamera(string name)
{
if (skip_camera_names == null)
skip_camera_names = new List<string>() { "Preview Camera", "Preview Scene Camera" };
return skip_camera_names.Contains(name);
}
public static IEnumerator GetRandomParticleData(int amount, List<Particle> result)
{
List<float> seeds = new List<float>();
seeds.AddRange(GetShuffleSeeds(amount));
List<float> factors = new List<float>();
factors.AddRange(GetShuffleSeeds(amount));
float radius = 2.0f;
const int mod = 1 << 13;
for (int i = 0; i < amount; i++)
{
float x = Random.Range(-1.0f, 1.0f);
float y = Random.Range(-1.0f, 1.0f);
float z = Random.Range(-1.0f, 1.0f);
float r = Mathf.Pow(Random.Range(0.0f, 1.0f), 1.0f / 2.2f) * radius;
Vector3 pos = (new Vector3(x, y, z)).normalized * r;
Particle p = new Particle();
p.position = pos;
p.seed = seeds[i];
p.color = new Vector4(1, 1, 1, factors[i]);
p.velocity = Vector3.zero;
p.life = Random.Range(1.0f, 0.0f);
var q = Random.rotation;
p.quat = new Vector4(q.x, q.y, q.z, q.w);
p.model_matrix = Matrix4x4.identity;
result.Add(p);
if (i % mod == 0)
{
yield return null;
}
}
}
public static IEnumerator GetReferencesParticleMesh(List<Mesh> referenceMeshes, int maxParticles, Mesh result)
{
int totalVertexCount = 0;
foreach (var m in referenceMeshes)
totalVertexCount += m.vertexCount;
int max_particles = maxParticles / referenceMeshes.Count;
int num_meshes = 1;
int ptc_per_mesh = max_particles / num_meshes;
//for (int i = 0; i < num_meshes; i++)
{
int i = 0;
var vertices = new List<Vector3>();
var normals = new List<Vector3>();
var colors = new List<Color>();
var uvs = new List<Vector2>();
var indices = new List<int>();
var custom_uvs = new List<Vector4>();
int begin_index = 0;
for (int j = 0; j < ptc_per_mesh; j++)
{
for (int k = 0; k < referenceMeshes.Count; k++)
{
int index = (i * ptc_per_mesh + j) * referenceMeshes.Count + k;
var mesh = referenceMeshes[k];
vertices.AddRange(mesh.vertices);
normals.AddRange(mesh.normals);
uvs.AddRange(mesh.uv);
if (mesh.colors.Length == mesh.vertices.Length)
{
colors.AddRange(mesh.colors);
}
else
{
for (int ci = 0; ci < mesh.vertices.Length; ci++)
colors.Add(Color.white);
}
foreach (var idx in mesh.GetIndices(0))
indices.Add(begin_index + idx);
for (int l = 0; l < mesh.vertexCount; l++)
custom_uvs.Add(new Vector4(mesh.uv[l].x, mesh.uv[l].y, index, k));
begin_index += mesh.vertexCount;
}
if (j % 1024 == 0)
{
yield return null;
}
}
//Mesh m = new Mesh();
if (vertices.Count > 65000)
result.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
result.SetVertices(vertices);
result.SetNormals(normals);
if (colors.Count == vertices.Count)
{
result.SetColors(colors);
}
//result.SetUVs(0, uvs);
result.SetUVs(0, custom_uvs);
result.SetIndices(indices.ToArray(), referenceMeshes[0].GetTopology(0), 0);
result.bounds = new Bounds(Vector3.zero, Vector3.one * 100);
result.UploadMeshData(false);
//meshes.Add(m);
}
yield return null;
}
}
}