Skip to content

Commit

Permalink
feat(simplifier): set manual uv component count
Browse files Browse the repository at this point in the history
  • Loading branch information
Whinarn committed Mar 26, 2021
1 parent 2be2b7a commit 9795860
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 165 deletions.
8 changes: 7 additions & 1 deletion Runtime/LODGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,12 @@ private static void CollectChildRenderersForLOD(Transform transform, List<Render

private static Mesh SimplifyMesh(Mesh mesh, float quality, SimplificationOptions options)
{
int uvComponentCount = -1;
if (options.ManualUVComponentCount)
{
uvComponentCount = options.UVComponentCount;
}

var meshSimplifier = new MeshSimplifier();
meshSimplifier.PreserveBorderEdges = options.PreserveBorderEdges;
meshSimplifier.PreserveUVSeamEdges = options.PreserveUVSeamEdges;
Expand All @@ -616,7 +622,7 @@ private static Mesh SimplifyMesh(Mesh mesh, float quality, SimplificationOptions
meshSimplifier.VertexLinkDistance = options.VertexLinkDistance;
meshSimplifier.MaxIterationCount = options.MaxIterationCount;
meshSimplifier.Agressiveness = options.Agressiveness;
meshSimplifier.Initialize(mesh);
meshSimplifier.Initialize(mesh, uvComponentCount);
meshSimplifier.SimplifyMesh(quality);

var simplifiedMesh = meshSimplifier.ToMesh();
Expand Down
222 changes: 67 additions & 155 deletions Runtime/MeshSimplifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1732,151 +1732,7 @@ public void GetUVs(int channel, List<Vector4> uvs)
/// </summary>
/// <param name="channel">The channel index.</param>
/// <param name="uvs">The UVs.</param>
public void SetUVs(int channel, Vector2[] uvs)
{
if (channel < 0 || channel >= UVChannelCount)
throw new ArgumentOutOfRangeException(nameof(channel));

if (uvs != null && uvs.Length > 0)
{
if (vertUV2D == null)
vertUV2D = new UVChannels<Vector2>();

int uvCount = uvs.Length;
var uvSet = vertUV2D[channel];
if (uvSet != null)
{
uvSet.Resize(uvCount);
}
else
{
uvSet = new ResizableArray<Vector2>(uvCount, uvCount);
vertUV2D[channel] = uvSet;
}

var uvData = uvSet.Data;
uvs.CopyTo(uvData, 0);
}
else
{
if (vertUV2D != null)
{
vertUV2D[channel] = null;
}
}

if (vertUV3D != null)
{
vertUV3D[channel] = null;
}
if (vertUV4D != null)
{
vertUV4D[channel] = null;
}
}

/// <summary>
/// Sets the UVs (3D) for a specific channel.
/// </summary>
/// <param name="channel">The channel index.</param>
/// <param name="uvs">The UVs.</param>
public void SetUVs(int channel, Vector3[] uvs)
{
if (channel < 0 || channel >= UVChannelCount)
throw new ArgumentOutOfRangeException(nameof(channel));

if (uvs != null && uvs.Length > 0)
{
if (vertUV3D == null)
vertUV3D = new UVChannels<Vector3>();

int uvCount = uvs.Length;
var uvSet = vertUV3D[channel];
if (uvSet != null)
{
uvSet.Resize(uvCount);
}
else
{
uvSet = new ResizableArray<Vector3>(uvCount, uvCount);
vertUV3D[channel] = uvSet;
}

var uvData = uvSet.Data;
uvs.CopyTo(uvData, 0);
}
else
{
if (vertUV3D != null)
{
vertUV3D[channel] = null;
}
}

if (vertUV2D != null)
{
vertUV2D[channel] = null;
}
if (vertUV4D != null)
{
vertUV4D[channel] = null;
}
}

/// <summary>
/// Sets the UVs (4D) for a specific channel.
/// </summary>
/// <param name="channel">The channel index.</param>
/// <param name="uvs">The UVs.</param>
public void SetUVs(int channel, Vector4[] uvs)
{
if (channel < 0 || channel >= UVChannelCount)
throw new ArgumentOutOfRangeException(nameof(channel));

if (uvs != null && uvs.Length > 0)
{
if (vertUV4D == null)
vertUV4D = new UVChannels<Vector4>();

int uvCount = uvs.Length;
var uvSet = vertUV4D[channel];
if (uvSet != null)
{
uvSet.Resize(uvCount);
}
else
{
uvSet = new ResizableArray<Vector4>(uvCount, uvCount);
vertUV4D[channel] = uvSet;
}

var uvData = uvSet.Data;
uvs.CopyTo(uvData, 0);
}
else
{
if (vertUV4D != null)
{
vertUV4D[channel] = null;
}
}

if (vertUV2D != null)
{
vertUV2D[channel] = null;
}
if (vertUV3D != null)
{
vertUV3D[channel] = null;
}
}

/// <summary>
/// Sets the UVs (2D) for a specific channel.
/// </summary>
/// <param name="channel">The channel index.</param>
/// <param name="uvs">The UVs.</param>
public void SetUVs(int channel, List<Vector2> uvs)
public void SetUVs(int channel, IList<Vector2> uvs)
{
if (channel < 0 || channel >= UVChannelCount)
throw new ArgumentOutOfRangeException(nameof(channel));
Expand Down Expand Up @@ -1924,7 +1780,7 @@ public void SetUVs(int channel, List<Vector2> uvs)
/// </summary>
/// <param name="channel">The channel index.</param>
/// <param name="uvs">The UVs.</param>
public void SetUVs(int channel, List<Vector3> uvs)
public void SetUVs(int channel, IList<Vector3> uvs)
{
if (channel < 0 || channel >= UVChannelCount)
throw new ArgumentOutOfRangeException(nameof(channel));
Expand Down Expand Up @@ -1972,7 +1828,7 @@ public void SetUVs(int channel, List<Vector3> uvs)
/// </summary>
/// <param name="channel">The channel index.</param>
/// <param name="uvs">The UVs.</param>
public void SetUVs(int channel, List<Vector4> uvs)
public void SetUVs(int channel, IList<Vector4> uvs)
{
if (channel < 0 || channel >= UVChannelCount)
throw new ArgumentOutOfRangeException(nameof(channel));
Expand Down Expand Up @@ -2016,24 +1872,26 @@ public void SetUVs(int channel, List<Vector4> uvs)
}

/// <summary>
/// Sets the UVs for a specific channel and automatically detects the used components.
/// Sets the UVs for a specific channel with a specific count of UV components.
/// </summary>
/// <param name="channel">The channel index.</param>
/// <param name="uvs">The UVs.</param>
public void SetUVsAuto(int channel, List<Vector4> uvs)
/// <param name="uvComponentCount">The count of UV components.</param>
public void SetUVs(int channel, IList<Vector4> uvs, int uvComponentCount)
{
if (channel < 0 || channel >= UVChannelCount)
throw new ArgumentOutOfRangeException(nameof(channel));
else if (uvComponentCount < 0 || uvComponentCount > 4)
throw new ArgumentOutOfRangeException(nameof(uvComponentCount));

if (uvs != null && uvs.Count > 0)
if (uvs != null && uvs.Count > 0 && uvComponentCount > 0)
{
int usedComponents = MeshUtils.GetUsedUVComponents(uvs);
if (usedComponents <= 2)
if (uvComponentCount <= 2)
{
var uv2D = MeshUtils.ConvertUVsTo2D(uvs);
SetUVs(channel, uv2D);
}
else if (usedComponents == 3)
else if (uvComponentCount == 3)
{
var uv3D = MeshUtils.ConvertUVsTo3D(uvs);
SetUVs(channel, uv3D);
Expand All @@ -2059,6 +1917,20 @@ public void SetUVsAuto(int channel, List<Vector4> uvs)
}
}
}

/// <summary>
/// Sets the UVs for a specific channel and automatically detects the used components.
/// </summary>
/// <param name="channel">The channel index.</param>
/// <param name="uvs">The UVs.</param>
public void SetUVsAuto(int channel, IList<Vector4> uvs)
{
if (channel < 0 || channel >= UVChannelCount)
throw new ArgumentOutOfRangeException(nameof(channel));

int uvComponentCount = MeshUtils.GetUsedUVComponents(uvs);
SetUVs(channel, uvs, uvComponentCount);
}
#endregion
#endregion

Expand Down Expand Up @@ -2153,12 +2025,25 @@ public void AddBlendShapes(BlendShape[] blendShapes)
#region Initialize
/// <summary>
/// Initializes the algorithm with the original mesh.
/// Will automatically detect the count of UV components used on the mesh.
/// </summary>
/// <param name="mesh">The mesh.</param>
public void Initialize(Mesh mesh)
{
Initialize(mesh, -1);
}

/// <summary>
/// Initializes the algorithm with the original mesh.
/// </summary>
/// <param name="mesh">The mesh.</param>
/// <param name="uvComponentCount">The count of UV components that are used on the mesh. -1 means that it will be automatically detected. Note that all UV channels would use the same UV component count.</param>
public void Initialize(Mesh mesh, int uvComponentCount)
{
if (mesh == null)
throw new ArgumentNullException(nameof(mesh));
if (uvComponentCount < -1 || uvComponentCount > 4)
throw new ArgumentOutOfRangeException(nameof(uvComponentCount));

this.Vertices = mesh.vertices;
this.Normals = mesh.normals;
Expand All @@ -2170,8 +2055,34 @@ public void Initialize(Mesh mesh)

for (int channel = 0; channel < UVChannelCount; channel++)
{
var uvs = MeshUtils.GetMeshUVs(mesh, channel);
SetUVsAuto(channel, uvs);
switch (uvComponentCount)
{
case -1:
{
var uvs = MeshUtils.GetMeshUVs(mesh, channel);
SetUVsAuto(channel, uvs);
break;
}
case 1:
case 2:
{
var uvs = MeshUtils.GetMeshUVs2D(mesh, channel);
SetUVs(channel, uvs);
break;
}
case 3:
{
var uvs = MeshUtils.GetMeshUVs3D(mesh, channel);
SetUVs(channel, uvs);
break;
}
case 4:
{
var uvs = MeshUtils.GetMeshUVs(mesh, channel);
SetUVs(channel, uvs);
break;
}
}
}

var blendShapes = MeshUtils.GetMeshBlendShapes(mesh);
Expand Down Expand Up @@ -2329,6 +2240,7 @@ public Mesh ToMesh()
List<Vector2>[] uvs2D = null;
List<Vector3>[] uvs3D = null;
List<Vector4>[] uvs4D = null;

if (vertUV2D != null)
{
uvs2D = new List<Vector2>[UVChannelCount];
Expand Down
18 changes: 16 additions & 2 deletions Runtime/SimplificationOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#region License
#region License
/*
MIT License
Expand Down Expand Up @@ -49,7 +49,9 @@ public struct SimplificationOptions
EnableSmartLink = true,
VertexLinkDistance = double.Epsilon,
MaxIterationCount = 100,
Agressiveness = 7.0
Agressiveness = 7.0,
ManualUVComponentCount = false,
UVComponentCount = 2
};

/// <summary>
Expand Down Expand Up @@ -104,5 +106,17 @@ public struct SimplificationOptions
/// </summary>
[Tooltip("The agressiveness of the mesh simplification. Higher number equals higher quality, but more expensive to run.")]
public double Agressiveness;
/// <summary>
/// If a manual UV component count should be used (set by UVComponentCount), instead of the automatic detection.
/// Default value: false
/// </summary>
[Tooltip("If a manual UV component count should be used (set by UV Component Count below), instead of the automatic detection.")]
public bool ManualUVComponentCount;
/// <summary>
/// The UV component count. The same UV component count will be used on all UV channels.
/// Default value: 2
/// </summary>
[Range(0, 4), Tooltip("The UV component count. The same UV component count will be used on all UV channels.")]
public int UVComponentCount;
}
}
Loading

0 comments on commit 9795860

Please # to comment.