using System;
using System.Collections.Generic;
using UnityEngine;
namespace ProceduralToolkit
{
///
/// Mesh extensions
///
public static class MeshE
{
///
/// Moves mesh vertices by
///
public static void Move(this Mesh mesh, Vector3 vector)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
var vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] += vector;
}
mesh.vertices = vertices;
}
///
/// Rotates mesh vertices by
///
public static void Rotate(this Mesh mesh, Quaternion rotation)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
var vertices = mesh.vertices;
var normals = mesh.normals;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] = rotation*vertices[i];
normals[i] = rotation*normals[i];
}
mesh.vertices = vertices;
mesh.normals = normals;
}
///
/// Scales mesh vertices uniformly by
///
public static void Scale(this Mesh mesh, float scale)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
var vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] *= scale;
}
mesh.vertices = vertices;
}
///
/// Scales mesh vertices non-uniformly by
///
public static void Scale(this Mesh mesh, Vector3 scale)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
var vertices = mesh.vertices;
var normals = mesh.normals;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] = Vector3.Scale(vertices[i], scale);
normals[i] = Vector3.Scale(normals[i], scale).normalized;
}
mesh.vertices = vertices;
mesh.normals = normals;
}
///
/// Paints mesh vertices with
///
public static void Paint(this Mesh mesh, Color color)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
var colors = new Color[mesh.vertexCount];
for (int i = 0; i < mesh.vertexCount; i++)
{
colors[i] = color;
}
mesh.colors = colors;
}
///
/// Flips mesh faces
///
public static void FlipFaces(this Mesh mesh)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
mesh.FlipTriangles();
mesh.FlipNormals();
}
///
/// Reverses the winding order of mesh triangles
///
public static void FlipTriangles(this Mesh mesh)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
for (int i = 0; i < mesh.subMeshCount; i++)
{
var triangles = mesh.GetTriangles(i);
for (int j = 0; j < triangles.Length; j += 3)
{
PTUtils.Swap(ref triangles[j], ref triangles[j + 1]);
}
mesh.SetTriangles(triangles, i);
}
}
///
/// Reverses the direction of mesh normals
///
public static void FlipNormals(this Mesh mesh)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
var normals = mesh.normals;
for (int i = 0; i < normals.Length; i++)
{
normals[i] = -normals[i];
}
mesh.normals = normals;
}
///
/// Flips the UV map horizontally in the selected
///
public static void FlipUVHorizontally(this Mesh mesh, int channel = 0)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
var list = new List();
mesh.GetUVs(channel, list);
for (var i = 0; i < list.Count; i++)
{
list[i] = new Vector2(1 - list[i].x, list[i].y);
}
mesh.SetUVs(channel, list);
}
///
/// Flips the UV map vertically in the selected
///
public static void FlipUVVertically(this Mesh mesh, int channel = 0)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
var list = new List();
mesh.GetUVs(channel, list);
for (var i = 0; i < list.Count; i++)
{
list[i] = new Vector2(list[i].x, 1 - list[i].y);
}
mesh.SetUVs(channel, list);
}
///
/// Projects vertices on a sphere with the given and , recalculates normals
///
public static void Spherify(this Mesh mesh, float radius, Vector3 center = default)
{
if (mesh == null)
{
throw new ArgumentNullException(nameof(mesh));
}
var vertices = mesh.vertices;
var normals = mesh.normals;
for (var i = 0; i < vertices.Length; i++)
{
normals[i] = (vertices[i] - center).normalized;
vertices[i] = normals[i]*radius;
}
mesh.vertices = vertices;
mesh.normals = normals;
}
}
}