OldBlueWater/BlueWater/Assets/NWH/Dynamic Water Physics 2/Scripts/Lib/MeshDecimate/Tri.cs
2023-12-19 11:31:29 +09:00

315 lines
7.8 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace NWH.DWP2.MeshDecimation
{
public class Tri
{
public int id;
public Vert v0;
public Vert v1;
public Vert v2;
public int defaultIndex0;
public int defaultIndex1;
public int defaultIndex2;
public Vector2 uv0;
public Vector2 uv1;
public Vector2 uv2;
public Vector3 vn0;
public Vector3 vn1;
public Vector3 vn2;
public Vector3 normal;
public bool deleted;
public Tri(int id, Vert v0, Vert v1, Vert v2, Vector2 uv0, Vector2 uv1, Vector2 uv2)
{
this.id = id;
this.v0 = v0;
this.v1 = v1;
this.v2 = v2;
this.uv0 = uv0;
this.uv1 = uv1;
this.uv2 = uv2;
RecalculateNormal();
v0.AddFace(this);
v1.AddFace(this);
v2.AddFace(this);
v0.AddNeighbor(v1);
v0.AddNeighbor(v2);
v1.AddNeighbor(v0);
v1.AddNeighbor(v2);
v2.AddNeighbor(v0);
v2.AddNeighbor(v1);
}
public void SetDefaultIndices(int n0, int n1, int n2)
{
defaultIndex0 = n0;
defaultIndex1 = n1;
defaultIndex2 = n2;
}
public void RemoveTriangle(History his)
{
v0.RemoveFace(this);
v1.RemoveFace(this);
v2.RemoveFace(this);
v0.RemoveIfNonNeighbor(v1);
v0.RemoveIfNonNeighbor(v2);
v1.RemoveIfNonNeighbor(v0);
v1.RemoveIfNonNeighbor(v2);
v2.RemoveIfNonNeighbor(v1);
v2.RemoveIfNonNeighbor(v0);
deleted = true;
his.RemovedTriangle(id);
}
public Vector2 uvAt(Vert v)
{
Vector3 vec = v.position;
if (vec == v0.position)
{
return uv0;
}
if (vec == v1.position)
{
return uv1;
}
if (vec == v2.position)
{
return uv2;
}
return new Vector2();
}
public Vector3 normalAt(Vert v)
{
Vector3 vec = v.position;
if (vec == v0.position)
{
return vn0;
}
if (vec == v1.position)
{
return vn1;
}
if (vec == v2.position)
{
return vn2;
}
return new Vector3();
}
public void setUV(Vert v, Vector2 newuv)
{
Vector3 vec = v.position;
if (vec == v0.position)
{
uv0 = newuv;
}
else if (vec == v1.position)
{
uv1 = newuv;
}
else if (vec == v2.position)
{
uv2 = newuv;
}
}
public void setVN(Vert v, Vector3 newNormal)
{
Vector3 vec = v.position;
if (vec == v0.position)
{
vn0 = newNormal;
}
else if (vec == v1.position)
{
vn1 = newNormal;
}
else if (vec == v2.position)
{
vn2 = newNormal;
}
}
public bool HasVertex(Vert v)
{
Vector3 vec = v.position;
return vec == v0.position || vec == v1.position || vec == v2.position;
}
public void RecalculateNormal()
{
Vector3 v1pos = v1.position;
normal = Vector3.Cross(v1pos - v0.position, v2.position - v1pos);
if (normal.magnitude == 0)
{
return;
}
normal.Normalize();
}
// Only called if 'Recalculate Normals' is enabled.
// This will smooth out normals event at uv seams.
public void RecalculateAvgNormals(float smoothAngleDot)
{
int i;
List<Tri> flist = new List<Tri>();
List<Tri> slist = new List<Tri>();
int n = flist.Count;
Tri f;
Vector3 fn;
flist = v0.face;
slist.Clear();
for (i = 0; i < n; ++i)
{
f = flist[i];
fn = f.normal;
if (fn.x * normal.x + fn.y * normal.y + fn.z * normal.z > smoothAngleDot)
{
vn0 += fn;
slist.Add(f);
}
}
vn0.Normalize();
n = slist.Count;
for (i = 0; i < n; ++i)
{
f = slist[i];
f.setVN(v0, vn0);
}
flist = v1.face;
n = flist.Count;
slist.Clear();
for (i = 0; i < n; ++i)
{
f = flist[i];
fn = f.normal;
if (fn.x * normal.x + fn.y * normal.y + fn.z * normal.z > smoothAngleDot)
{
vn1 += fn;
slist.Add(f);
}
}
vn1.Normalize();
n = slist.Count;
for (i = 0; i < n; ++i)
{
f = slist[i];
f.setVN(v1, vn1);
}
flist = v2.face;
n = flist.Count;
slist.Clear();
for (i = 0; i < n; ++i)
{
f = flist[i];
fn = f.normal;
if (fn.x * normal.x + fn.y * normal.y + fn.z * normal.z > smoothAngleDot)
{
vn2 += fn;
slist.Add(f);
}
}
vn2.Normalize();
n = slist.Count;
for (i = 0; i < n; ++i)
{
f = slist[i];
f.setVN(v2, vn2);
}
}
public void ReplaceVertex(Vert vo, Vert vnew, Vector2 newUV, Vector3 newVN, History his)
{
Vector3 vec = vo.position;
Vert changedVertex = v2;
int changedVertexId = 2;
Vector3 changedNormal = vn2;
Vector2 changedUV = uv2;
if (vec == v0.position)
{
changedVertex = v0;
changedVertexId = 0;
changedNormal = vn0;
changedUV = uv0;
v0 = vnew;
vn0 = newVN;
uv0 = newUV;
}
else if (vec == v1.position)
{
changedVertex = v1;
changedVertexId = 1;
changedNormal = vn1;
changedUV = uv1;
v1 = vnew;
vn1 = newVN;
uv1 = newUV;
}
else
{
v2 = vnew;
vn2 = newVN;
uv2 = newUV;
}
vo.RemoveFace(this);
vnew.AddFace(this);
vo.RemoveIfNonNeighbor(v0);
v0.RemoveIfNonNeighbor(vo);
vo.RemoveIfNonNeighbor(v1);
v1.RemoveIfNonNeighbor(vo);
vo.RemoveIfNonNeighbor(v2);
v2.RemoveIfNonNeighbor(vo);
v0.AddNeighbor(v1);
v0.AddNeighbor(v2);
v1.AddNeighbor(v0);
v1.AddNeighbor(v2);
v2.AddNeighbor(v0);
v2.AddNeighbor(v1);
RecalculateNormal();
his.ReplaceVertex(id, changedVertexId, changedVertex.id, changedNormal, changedUV, vnew.id, newVN, newUV);
}
}
}