127 lines
4.6 KiB
C#
127 lines
4.6 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Obi
|
|
{
|
|
public class ObiParticleEditorDrawing : MonoBehaviour
|
|
{
|
|
public static Mesh particlesMesh;
|
|
public static Material particleMaterial;
|
|
|
|
private static void CreateParticlesMesh()
|
|
{
|
|
if (particlesMesh == null)
|
|
{
|
|
particlesMesh = new Mesh();
|
|
particlesMesh.hideFlags = HideFlags.HideAndDontSave;
|
|
}
|
|
}
|
|
|
|
private static void CreateParticleMaterials()
|
|
{
|
|
if (!particleMaterial)
|
|
{
|
|
particleMaterial = Resources.Load<Material>("EditorParticle");
|
|
}
|
|
}
|
|
|
|
public static void DestroyParticlesMesh()
|
|
{
|
|
GameObject.DestroyImmediate(particlesMesh);
|
|
}
|
|
|
|
public static void DrawParticles(Camera cam, ObiActorBlueprint blueprint, int activeParticle, bool[] visible, Color[] baseColor, int[] sortedIndices, float radiusScale = 1)
|
|
{
|
|
CreateParticlesMesh();
|
|
CreateParticleMaterials();
|
|
|
|
if (!particleMaterial.SetPass(0))
|
|
return;
|
|
|
|
//because each vertex needs to be drawn as a quad.
|
|
int particlesPerDrawcall = Constants.maxVertsPerMesh / 4;
|
|
int drawcallCount = blueprint.particleCount / particlesPerDrawcall + 1;
|
|
particlesPerDrawcall = Mathf.Min(particlesPerDrawcall, blueprint.particleCount);
|
|
|
|
List<Vector3> vertices = new List<Vector3>(blueprint.activeParticleCount* 4);
|
|
List<Vector3> normals = new List<Vector3>(blueprint.activeParticleCount * 4);
|
|
List<Vector4> uvs = new List<Vector4>(blueprint.activeParticleCount * 4);
|
|
List<Color> colors = new List<Color>(blueprint.activeParticleCount * 4);
|
|
List<int> triangles = new List<int>(blueprint.activeParticleCount * 6);
|
|
|
|
Vector3 particleOffset0 = new Vector3(1, 1, 0);
|
|
Vector3 particleOffset1 = new Vector3(-1, 1, 0);
|
|
Vector3 particleOffset2 = new Vector3(-1, -1, 0);
|
|
Vector3 particleOffset3 = new Vector3(1, -1, 0);
|
|
|
|
Vector4 radius = new Vector4(1, 0, 0, 0.005f * radiusScale);
|
|
|
|
for (int i = 0; i < drawcallCount; ++i)
|
|
{
|
|
//Draw all cloth vertices:
|
|
particlesMesh.Clear();
|
|
vertices.Clear();
|
|
uvs.Clear();
|
|
normals.Clear();
|
|
colors.Clear();
|
|
triangles.Clear();
|
|
|
|
int index = 0;
|
|
|
|
// Run over all particles (not only active ones), since they're reordered based on distance to camera.
|
|
// Then test if the sorted index is active or not, and skip inactive ones.
|
|
int limit = Mathf.Min((i + 1) * particlesPerDrawcall, blueprint.particleCount);
|
|
|
|
for (int j = i * particlesPerDrawcall; j < limit; ++j)
|
|
{
|
|
int sortedIndex = sortedIndices[j];
|
|
|
|
// skip inactive ones:
|
|
if (!blueprint.IsParticleActive(sortedIndex))
|
|
continue;
|
|
|
|
normals.Add(particleOffset0);
|
|
normals.Add(particleOffset1);
|
|
normals.Add(particleOffset2);
|
|
normals.Add(particleOffset3);
|
|
|
|
uvs.Add(radius);
|
|
uvs.Add(radius);
|
|
uvs.Add(radius);
|
|
uvs.Add(radius);
|
|
|
|
vertices.Add(blueprint.positions[sortedIndex]);
|
|
vertices.Add(blueprint.positions[sortedIndex]);
|
|
vertices.Add(blueprint.positions[sortedIndex]);
|
|
vertices.Add(blueprint.positions[sortedIndex]);
|
|
|
|
colors.Add(baseColor[sortedIndex]);
|
|
colors.Add(baseColor[sortedIndex]);
|
|
colors.Add(baseColor[sortedIndex]);
|
|
colors.Add(baseColor[sortedIndex]);
|
|
|
|
triangles.Add(index + 2);
|
|
triangles.Add(index + 1);
|
|
triangles.Add(index);
|
|
triangles.Add(index + 3);
|
|
triangles.Add(index + 2);
|
|
triangles.Add(index);
|
|
|
|
index += 4;
|
|
}
|
|
|
|
particlesMesh.SetVertices(vertices);
|
|
particlesMesh.SetNormals(normals);
|
|
particlesMesh.SetColors(colors);
|
|
particlesMesh.SetUVs(0, uvs);
|
|
particlesMesh.SetTriangles(triangles,0, true);
|
|
|
|
Graphics.DrawMeshNow(particlesMesh, Matrix4x4.identity);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
} |