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
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|