118 lines
4.5 KiB
C#
118 lines
4.5 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace Obi
|
|
{
|
|
public abstract class ObiClothBlueprintBase : ObiMeshBasedActorBlueprint
|
|
{
|
|
[SerializeField] [HideInInspector] public HalfEdgeMesh topology; /**< Topology generated from the input mesh.*/
|
|
|
|
[HideInInspector] public int[] deformableTriangles = null; /**< Indices of deformable triangles (3 per triangle)*/
|
|
[HideInInspector] public Vector3[] restNormals = null;
|
|
[HideInInspector] public float[] areaContribution = null; /**< How much mesh surface area each particle represents.*/
|
|
|
|
public const float DEFAULT_PARTICLE_MASS = 0.1f;
|
|
|
|
protected GraphColoring colorizer;
|
|
|
|
public HalfEdgeMesh Topology
|
|
{
|
|
get { return topology; }
|
|
}
|
|
|
|
protected override void SwapWithFirstInactiveParticle(int index)
|
|
{
|
|
base.SwapWithFirstInactiveParticle(index);
|
|
|
|
areaContribution.Swap(index, m_ActiveParticleCount);
|
|
restNormals.Swap(index, m_ActiveParticleCount);
|
|
|
|
// Keep topology in sync:
|
|
if (topology != null && topology.containsData)
|
|
{
|
|
topology.SwapVertices(index, m_ActiveParticleCount);
|
|
}
|
|
|
|
// Keep deformable triangles in sync:
|
|
for (int i = 0; i < deformableTriangles.Length; ++i)
|
|
{
|
|
if (deformableTriangles[i] == index)
|
|
deformableTriangles[i] = m_ActiveParticleCount;
|
|
else if (deformableTriangles[i] == m_ActiveParticleCount)
|
|
deformableTriangles[i] = index;
|
|
}
|
|
}
|
|
|
|
protected virtual IEnumerator GenerateDeformableTriangles()
|
|
{
|
|
deformableTriangles = new int[topology.faces.Count * 3];
|
|
restNormals = new Vector3[topology.vertices.Count];
|
|
|
|
// Generate deformable triangles:
|
|
for (int i = 0; i < topology.faces.Count; i++)
|
|
{
|
|
HalfEdgeMesh.Face face = topology.faces[i];
|
|
|
|
HalfEdgeMesh.HalfEdge e1 = topology.halfEdges[face.halfEdge];
|
|
HalfEdgeMesh.HalfEdge e2 = topology.halfEdges[e1.nextHalfEdge];
|
|
HalfEdgeMesh.HalfEdge e3 = topology.halfEdges[e2.nextHalfEdge];
|
|
|
|
deformableTriangles[i * 3] = e1.endVertex;
|
|
deformableTriangles[i * 3 + 1] = e2.endVertex;
|
|
deformableTriangles[i * 3 + 2] = e3.endVertex;
|
|
|
|
Vector3 v1 = positions[e1.endVertex];
|
|
Vector3 v2 = positions[e2.endVertex];
|
|
Vector3 v3 = positions[e3.endVertex];
|
|
|
|
Vector3 n = Vector3.Cross(v2 - v1, v3 - v1);
|
|
|
|
restNormals[e1.endVertex] += n;
|
|
restNormals[e2.endVertex] += n;
|
|
restNormals[e3.endVertex] += n;
|
|
|
|
if (i % 500 == 0)
|
|
yield return new CoroutineJob.ProgressInfo("ObiCloth: generating deformable geometry...", i / (float)topology.faces.Count);
|
|
}
|
|
|
|
for (int i = 0; i < restNormals.Length; ++i)
|
|
restNormals[i].Normalize();
|
|
}
|
|
|
|
protected virtual IEnumerator CreateSimplices()
|
|
{
|
|
triangles = new int[topology.faces.Count * 3];
|
|
restNormals = new Vector3[topology.vertices.Count];
|
|
|
|
// Generate deformable triangles:
|
|
for (int i = 0; i < topology.faces.Count; i++)
|
|
{
|
|
HalfEdgeMesh.Face face = topology.faces[i];
|
|
|
|
HalfEdgeMesh.HalfEdge e1 = topology.halfEdges[face.halfEdge];
|
|
HalfEdgeMesh.HalfEdge e2 = topology.halfEdges[e1.nextHalfEdge];
|
|
HalfEdgeMesh.HalfEdge e3 = topology.halfEdges[e2.nextHalfEdge];
|
|
|
|
triangles[i * 3] = e1.endVertex;
|
|
triangles[i * 3 + 1] = e2.endVertex;
|
|
triangles[i * 3 + 2] = e3.endVertex;
|
|
|
|
Vector3 v1 = positions[e1.endVertex];
|
|
Vector3 v2 = positions[e2.endVertex];
|
|
Vector3 v3 = positions[e3.endVertex];
|
|
|
|
Vector3 n = Vector3.Cross(v2 - v1, v3 - v1);
|
|
|
|
restNormals[e1.endVertex] += n;
|
|
restNormals[e2.endVertex] += n;
|
|
restNormals[e3.endVertex] += n;
|
|
|
|
if (i % 500 == 0)
|
|
yield return new CoroutineJob.ProgressInfo("ObiCloth: generating deformable geometry...", i / (float)topology.faces.Count);
|
|
}
|
|
|
|
for (int i = 0; i < restNormals.Length; ++i)
|
|
restNormals[i].Normalize();
|
|
}
|
|
}
|
|
} |