111
This commit is contained in:
862
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/MeshSimplify.cs
vendored
Normal file
862
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/MeshSimplify.cs
vendored
Normal file
@@ -0,0 +1,862 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UltimateGameTools.MeshSimplifier;
|
||||
|
||||
public class MeshSimplify : MonoBehaviour
|
||||
{
|
||||
public bool RecurseIntoChildren
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_bGenerateIncludeChildren;
|
||||
}
|
||||
}
|
||||
|
||||
public Simplifier MeshSimplifier
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_meshSimplifier;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_meshSimplifier = value;
|
||||
}
|
||||
}
|
||||
|
||||
[HideInInspector]
|
||||
public Mesh m_originalMesh = null;
|
||||
|
||||
[HideInInspector]
|
||||
public Mesh m_simplifiedMesh = null;
|
||||
|
||||
[HideInInspector]
|
||||
public bool m_bEnablePrefabUsage = false;
|
||||
|
||||
[HideInInspector]
|
||||
public float m_fVertexAmount = 1.0f;
|
||||
|
||||
[HideInInspector]
|
||||
public string m_strAssetPath = null;
|
||||
|
||||
[HideInInspector]
|
||||
public MeshSimplify m_meshSimplifyRoot;
|
||||
|
||||
[HideInInspector]
|
||||
public List<MeshSimplify> m_listDependentChildren = new List<MeshSimplify>();
|
||||
|
||||
[HideInInspector]
|
||||
public bool m_bExpandRelevanceSpheres = true;
|
||||
|
||||
public RelevanceSphere[] m_aRelevanceSpheres = null;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private Simplifier m_meshSimplifier = null;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private bool m_bGenerateIncludeChildren = true;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private bool m_bOverrideRootSettings = false;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private bool m_bUseEdgeLength = true, m_bUseCurvature = true, m_bProtectTexture = true, m_bLockBorder = true;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private bool m_bDataDirty = true;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private bool m_bExcludedFromTree = false;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public void OnDrawGizmos()
|
||||
{
|
||||
if (m_meshSimplifyRoot != null)
|
||||
{
|
||||
if (m_meshSimplifyRoot.m_bExpandRelevanceSpheres == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bExpandRelevanceSpheres == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Gizmos.color = Color.red;
|
||||
|
||||
RelevanceSphere[] aRelevanceSpheres = m_meshSimplifyRoot != null ? m_meshSimplifyRoot.m_aRelevanceSpheres : m_aRelevanceSpheres;
|
||||
|
||||
if (aRelevanceSpheres == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool bDrawVertices = false;
|
||||
|
||||
for (int i = 0; i < UnityEditor.Selection.gameObjects.Length; i++)
|
||||
{
|
||||
if (((UnityEditor.Selection.gameObjects[i] == this.gameObject) && m_meshSimplifyRoot == null) || ((m_meshSimplifyRoot != null) && (UnityEditor.Selection.gameObjects[i] == m_meshSimplifyRoot.gameObject)))
|
||||
{
|
||||
bDrawVertices = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bDrawVertices == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3[] aVerticesWorld = Simplifier.GetWorldVertices(this.gameObject);
|
||||
|
||||
if(aVerticesWorld == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix4x4[] aSphereMatrices = new Matrix4x4[aRelevanceSpheres.Length];
|
||||
|
||||
for (int nSphere = 0; nSphere < aRelevanceSpheres.Length; nSphere++)
|
||||
{
|
||||
aSphereMatrices[nSphere] = Matrix4x4.TRS(aRelevanceSpheres[nSphere].m_v3Position, Quaternion.Euler(aRelevanceSpheres[nSphere].m_v3Rotation), aRelevanceSpheres[nSphere].m_v3Scale).inverse;
|
||||
}
|
||||
|
||||
for (int nVertex = 0; nVertex < aVerticesWorld.Length; nVertex++)
|
||||
{
|
||||
for (int nSphere = 0; nSphere < aRelevanceSpheres.Length; nSphere++)
|
||||
{
|
||||
if (aRelevanceSpheres[nSphere].m_bExpanded)
|
||||
{
|
||||
Vector3 v3VertexSphereLocal = aSphereMatrices[nSphere].MultiplyPoint(aVerticesWorld[nVertex]);
|
||||
|
||||
if (v3VertexSphereLocal.magnitude <= 0.5)
|
||||
{
|
||||
Gizmos.DrawCube(aVerticesWorld[nVertex], Vector3.one * UnityEditor.HandleUtility.GetHandleSize(aVerticesWorld[nVertex]) * 0.05f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public static bool HasValidMeshData(GameObject go)
|
||||
{
|
||||
MeshFilter meshFilter = go.GetComponent<MeshFilter>();
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SkinnedMeshRenderer skin = go.GetComponent<SkinnedMeshRenderer>();
|
||||
|
||||
if (skin != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsRootOrBelongsToTree(MeshSimplify meshSimplify, MeshSimplify root)
|
||||
{
|
||||
if (meshSimplify == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (meshSimplify.m_bExcludedFromTree == false) && ((meshSimplify.m_meshSimplifyRoot == null) || (meshSimplify.m_meshSimplifyRoot == root) || (meshSimplify == root) || (meshSimplify.m_meshSimplifyRoot == root.m_meshSimplifyRoot));
|
||||
}
|
||||
|
||||
public bool IsGenerateIncludeChildrenActive()
|
||||
{
|
||||
return m_bGenerateIncludeChildren;
|
||||
}
|
||||
|
||||
public bool HasDependentChildren()
|
||||
{
|
||||
return m_listDependentChildren != null && m_listDependentChildren.Count > 0;
|
||||
}
|
||||
|
||||
public bool HasDataDirty()
|
||||
{
|
||||
return m_bDataDirty;
|
||||
}
|
||||
|
||||
public bool SetDataDirty(bool bDirty)
|
||||
{
|
||||
return m_bDataDirty = bDirty;
|
||||
}
|
||||
|
||||
public bool HasNonMeshSimplifyGameObjectsInTree()
|
||||
{
|
||||
return HasNonMeshSimplifyGameObjectsInTreeRecursive(this, this.gameObject);
|
||||
}
|
||||
|
||||
private bool HasNonMeshSimplifyGameObjectsInTreeRecursive(MeshSimplify root, GameObject gameObject)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify == null && HasValidMeshData(gameObject))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
if(HasNonMeshSimplifyGameObjectsInTreeRecursive(root, gameObject.transform.GetChild(nChild).gameObject))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ConfigureSimplifier()
|
||||
{
|
||||
m_meshSimplifier.UseEdgeLength = (m_meshSimplifyRoot != null && m_bOverrideRootSettings == false) ? m_meshSimplifyRoot.m_bUseEdgeLength : m_bUseEdgeLength;
|
||||
m_meshSimplifier.UseCurvature = (m_meshSimplifyRoot != null && m_bOverrideRootSettings == false) ? m_meshSimplifyRoot.m_bUseCurvature : m_bUseCurvature;
|
||||
m_meshSimplifier.ProtectTexture = (m_meshSimplifyRoot != null && m_bOverrideRootSettings == false) ? m_meshSimplifyRoot.m_bProtectTexture : m_bProtectTexture;
|
||||
m_meshSimplifier.LockBorder = (m_meshSimplifyRoot != null && m_bOverrideRootSettings == false) ? m_meshSimplifyRoot.m_bLockBorder : m_bLockBorder;
|
||||
}
|
||||
|
||||
public Simplifier GetMeshSimplifier()
|
||||
{
|
||||
return m_meshSimplifier;
|
||||
}
|
||||
|
||||
public void ComputeData(bool bRecurseIntoChildren, Simplifier.ProgressDelegate progress = null)
|
||||
{
|
||||
ComputeDataRecursive(this, this.gameObject, bRecurseIntoChildren, progress);
|
||||
}
|
||||
|
||||
private static void ComputeDataRecursive(MeshSimplify root, GameObject gameObject, bool bRecurseIntoChildren, Simplifier.ProgressDelegate progress = null)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify == null && root.m_bGenerateIncludeChildren)
|
||||
{
|
||||
if (HasValidMeshData(gameObject))
|
||||
{
|
||||
meshSimplify = gameObject.AddComponent<MeshSimplify>();
|
||||
meshSimplify.m_meshSimplifyRoot = root;
|
||||
root.m_listDependentChildren.Add(meshSimplify);
|
||||
}
|
||||
}
|
||||
|
||||
if(meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
meshSimplify.FreeData(false);
|
||||
|
||||
MeshFilter meshFilter = meshSimplify.GetComponent<MeshFilter>();
|
||||
|
||||
if (meshFilter != null && meshFilter.sharedMesh != null)
|
||||
{
|
||||
if (meshFilter.sharedMesh.vertexCount > 0)
|
||||
{
|
||||
if (meshSimplify.m_originalMesh == null)
|
||||
{
|
||||
meshSimplify.m_originalMesh = meshFilter.sharedMesh;
|
||||
}
|
||||
|
||||
Simplifier[] simplifiers = meshSimplify.GetComponents<Simplifier>();
|
||||
|
||||
for (int c = 0; c < simplifiers.Length; c++)
|
||||
{
|
||||
if (Application.isEditor && Application.isPlaying == false)
|
||||
{
|
||||
DestroyImmediate(simplifiers[c]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(simplifiers[c]);
|
||||
}
|
||||
}
|
||||
|
||||
meshSimplify.m_meshSimplifier = meshSimplify.gameObject.AddComponent<Simplifier>();
|
||||
meshSimplify.m_meshSimplifier.hideFlags = HideFlags.HideInInspector;
|
||||
meshSimplify.ConfigureSimplifier();
|
||||
|
||||
IEnumerator enumerator = meshSimplify.m_meshSimplifier.ProgressiveMesh(gameObject, meshSimplify.m_originalMesh, root.m_aRelevanceSpheres, meshSimplify.name, progress);
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SkinnedMeshRenderer skin = meshSimplify.GetComponent<SkinnedMeshRenderer>();
|
||||
|
||||
if (skin != null)
|
||||
{
|
||||
if (skin.sharedMesh.vertexCount > 0)
|
||||
{
|
||||
if (meshSimplify.m_originalMesh == null)
|
||||
{
|
||||
meshSimplify.m_originalMesh = skin.sharedMesh;
|
||||
}
|
||||
|
||||
Simplifier[] simplifiers = meshSimplify.GetComponents<Simplifier>();
|
||||
|
||||
for (int c = 0; c < simplifiers.Length; c++)
|
||||
{
|
||||
if (Application.isEditor && Application.isPlaying == false)
|
||||
{
|
||||
DestroyImmediate(simplifiers[c]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(simplifiers[c]);
|
||||
}
|
||||
}
|
||||
|
||||
meshSimplify.m_meshSimplifier = meshSimplify.gameObject.AddComponent<Simplifier>();
|
||||
meshSimplify.m_meshSimplifier.hideFlags = HideFlags.HideInInspector;
|
||||
meshSimplify.ConfigureSimplifier();
|
||||
|
||||
IEnumerator enumerator = meshSimplify.m_meshSimplifier.ProgressiveMesh(gameObject, meshSimplify.m_originalMesh, root.m_aRelevanceSpheres, meshSimplify.name, progress);
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meshSimplify.m_bDataDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
ComputeDataRecursive(root, gameObject.transform.GetChild(nChild).gameObject, bRecurseIntoChildren, progress);
|
||||
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasData()
|
||||
{
|
||||
return (m_meshSimplifier != null && m_simplifiedMesh != null) || (m_listDependentChildren != null && m_listDependentChildren.Count != 0);
|
||||
}
|
||||
|
||||
public bool HasSimplifiedMesh()
|
||||
{
|
||||
return m_simplifiedMesh != null && m_simplifiedMesh.vertexCount > 0;
|
||||
}
|
||||
|
||||
public void ComputeMesh(bool bRecurseIntoChildren, Simplifier.ProgressDelegate progress = null)
|
||||
{
|
||||
ComputeMeshRecursive(this, this.gameObject, bRecurseIntoChildren, progress);
|
||||
}
|
||||
|
||||
private static void ComputeMeshRecursive(MeshSimplify root, GameObject gameObject, bool bRecurseIntoChildren, Simplifier.ProgressDelegate progress = null)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_meshSimplifier != null)
|
||||
{
|
||||
if (meshSimplify.m_simplifiedMesh)
|
||||
{
|
||||
meshSimplify.m_simplifiedMesh.Clear();
|
||||
}
|
||||
|
||||
float fAmount = meshSimplify.m_fVertexAmount;
|
||||
|
||||
if (meshSimplify.m_bOverrideRootSettings == false && meshSimplify.m_meshSimplifyRoot != null)
|
||||
{
|
||||
fAmount = meshSimplify.m_meshSimplifyRoot.m_fVertexAmount;
|
||||
}
|
||||
|
||||
if (meshSimplify.m_simplifiedMesh == null)
|
||||
{
|
||||
meshSimplify.m_simplifiedMesh = CreateNewEmptyMesh(meshSimplify);
|
||||
}
|
||||
|
||||
meshSimplify.ConfigureSimplifier();
|
||||
|
||||
IEnumerator enumerator = meshSimplify.m_meshSimplifier.ComputeMeshWithVertexCount(gameObject, meshSimplify.m_simplifiedMesh, Mathf.RoundToInt(fAmount * meshSimplify.m_meshSimplifier.GetOriginalMeshUniqueVertexCount()), meshSimplify.name + " Simplified", progress);
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
ComputeMeshRecursive(root, gameObject.transform.GetChild(nChild).gameObject, bRecurseIntoChildren, progress);
|
||||
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignSimplifiedMesh(bool bRecurseIntoChildren)
|
||||
{
|
||||
AssignSimplifiedMeshRecursive(this, this.gameObject, bRecurseIntoChildren);
|
||||
}
|
||||
|
||||
private static void AssignSimplifiedMeshRecursive(MeshSimplify root, GameObject gameObject, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_simplifiedMesh != null)
|
||||
{
|
||||
MeshFilter meshFilter = meshSimplify.GetComponent<MeshFilter>();
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
meshFilter.sharedMesh = meshSimplify.m_simplifiedMesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
SkinnedMeshRenderer skin = meshSimplify.GetComponent<SkinnedMeshRenderer>();
|
||||
|
||||
if (skin != null)
|
||||
{
|
||||
skin.sharedMesh = meshSimplify.m_simplifiedMesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
AssignSimplifiedMeshRecursive(root, gameObject.transform.GetChild(nChild).gameObject, bRecurseIntoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RestoreOriginalMesh(bool bDeleteData, bool bRecurseIntoChildren)
|
||||
{
|
||||
RestoreOriginalMeshRecursive(this, this.gameObject, bDeleteData, bRecurseIntoChildren);
|
||||
}
|
||||
|
||||
private static void RestoreOriginalMeshRecursive(MeshSimplify root, GameObject gameObject, bool bDeleteData, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_originalMesh != null)
|
||||
{
|
||||
MeshFilter meshFilter = meshSimplify.GetComponent<MeshFilter>();
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
meshFilter.sharedMesh = meshSimplify.m_originalMesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
SkinnedMeshRenderer skin = meshSimplify.GetComponent<SkinnedMeshRenderer>();
|
||||
|
||||
if (skin != null)
|
||||
{
|
||||
skin.sharedMesh = meshSimplify.m_originalMesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bDeleteData)
|
||||
{
|
||||
meshSimplify.FreeData(false);
|
||||
meshSimplify.m_listDependentChildren.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
RestoreOriginalMeshRecursive(root, gameObject.transform.GetChild(nChild).gameObject, bDeleteData, bRecurseIntoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasOriginalMeshActive(bool bRecurseIntoChildren)
|
||||
{
|
||||
return HasOriginalMeshActiveRecursive(this, this.gameObject, bRecurseIntoChildren);
|
||||
}
|
||||
|
||||
private static bool HasOriginalMeshActiveRecursive(MeshSimplify root, GameObject gameObject, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
bool bHasOriginalMeshActive = false;
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_originalMesh != null)
|
||||
{
|
||||
MeshFilter meshFilter = meshSimplify.GetComponent<MeshFilter>();
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
if(meshFilter.sharedMesh == meshSimplify.m_originalMesh)
|
||||
{
|
||||
bHasOriginalMeshActive = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SkinnedMeshRenderer skin = meshSimplify.GetComponent<SkinnedMeshRenderer>();
|
||||
|
||||
if (skin != null)
|
||||
{
|
||||
if(skin.sharedMesh == meshSimplify.m_originalMesh)
|
||||
{
|
||||
bHasOriginalMeshActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
bHasOriginalMeshActive = bHasOriginalMeshActive || HasOriginalMeshActiveRecursive(root, gameObject.transform.GetChild(nChild).gameObject, bRecurseIntoChildren);
|
||||
}
|
||||
}
|
||||
|
||||
return bHasOriginalMeshActive;
|
||||
}
|
||||
|
||||
public bool HasVertexData(bool bRecurseIntoChildren)
|
||||
{
|
||||
return HasVertexDataRecursive(this, this.gameObject, bRecurseIntoChildren);
|
||||
}
|
||||
|
||||
private static bool HasVertexDataRecursive(MeshSimplify root, GameObject gameObject, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_simplifiedMesh && meshSimplify.m_simplifiedMesh.vertexCount > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
if (HasVertexDataRecursive(root, gameObject.transform.GetChild(nChild).gameObject, bRecurseIntoChildren))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int GetOriginalVertexCount(bool bRecurseIntoChildren)
|
||||
{
|
||||
int nVertexCount = 0;
|
||||
GetOriginalVertexCountRecursive(this, this.gameObject, ref nVertexCount, bRecurseIntoChildren);
|
||||
return nVertexCount;
|
||||
}
|
||||
|
||||
private static void GetOriginalVertexCountRecursive(MeshSimplify root, GameObject gameObject, ref int nVertexCount, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_originalMesh != null)
|
||||
{
|
||||
nVertexCount += meshSimplify.m_originalMesh.vertexCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
GetOriginalVertexCountRecursive(root, gameObject.transform.GetChild(nChild).gameObject, ref nVertexCount, bRecurseIntoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetOriginalTriangleCount(bool bRecurseIntoChildren)
|
||||
{
|
||||
int nTriangleCount = 0;
|
||||
GetOriginalTriangleCountRecursive(this, this.gameObject, ref nTriangleCount, bRecurseIntoChildren);
|
||||
return nTriangleCount;
|
||||
}
|
||||
|
||||
private static void GetOriginalTriangleCountRecursive(MeshSimplify root, GameObject gameObject, ref int nTriangleCount, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_originalMesh != null)
|
||||
{
|
||||
nTriangleCount += meshSimplify.m_originalMesh.triangles.Length / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
GetOriginalTriangleCountRecursive(root, gameObject.transform.GetChild(nChild).gameObject, ref nTriangleCount, bRecurseIntoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetSimplifiedVertexCount(bool bRecurseIntoChildren)
|
||||
{
|
||||
int nVertexCount = 0;
|
||||
GetSimplifiedVertexCountRecursive(this, this.gameObject, ref nVertexCount, bRecurseIntoChildren);
|
||||
return nVertexCount;
|
||||
}
|
||||
|
||||
private static void GetSimplifiedVertexCountRecursive(MeshSimplify root, GameObject gameObject, ref int nVertexCount, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_simplifiedMesh != null)
|
||||
{
|
||||
nVertexCount += meshSimplify.m_simplifiedMesh.vertexCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
GetSimplifiedVertexCountRecursive(root, gameObject.transform.GetChild(nChild).gameObject, ref nVertexCount, bRecurseIntoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetSimplifiedTriangleCount(bool bRecurseIntoChildren)
|
||||
{
|
||||
int nTriangleCount = 0;
|
||||
GetSimplifiedTriangleCountRecursive(this, this.gameObject, ref nTriangleCount, bRecurseIntoChildren);
|
||||
return nTriangleCount;
|
||||
}
|
||||
|
||||
private static void GetSimplifiedTriangleCountRecursive(MeshSimplify root, GameObject gameObject, ref int nTriangleCount, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_simplifiedMesh != null)
|
||||
{
|
||||
nTriangleCount += meshSimplify.m_simplifiedMesh.triangles.Length / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
GetSimplifiedTriangleCountRecursive(root, gameObject.transform.GetChild(nChild).gameObject, ref nTriangleCount, bRecurseIntoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveFromTree()
|
||||
{
|
||||
if (m_meshSimplifyRoot != null)
|
||||
{
|
||||
m_meshSimplifyRoot.m_listDependentChildren.Remove(this);
|
||||
}
|
||||
|
||||
RestoreOriginalMesh(true, false);
|
||||
|
||||
m_bExcludedFromTree = true;
|
||||
}
|
||||
|
||||
public void FreeData(bool bRecurseIntoChildren)
|
||||
{
|
||||
FreeDataRecursive(this, this.gameObject, bRecurseIntoChildren);
|
||||
}
|
||||
|
||||
private static void FreeDataRecursive(MeshSimplify root, GameObject gameObject, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_simplifiedMesh)
|
||||
{
|
||||
meshSimplify.m_simplifiedMesh.Clear();
|
||||
}
|
||||
|
||||
Simplifier[] simplifiers = gameObject.GetComponents<Simplifier>();
|
||||
|
||||
for (int c = 0; c < simplifiers.Length; c++)
|
||||
{
|
||||
if (Application.isEditor && Application.isPlaying == false)
|
||||
{
|
||||
DestroyImmediate(simplifiers[c]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(simplifiers[c]);
|
||||
}
|
||||
}
|
||||
|
||||
meshSimplify.m_bDataDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
FreeDataRecursive(root, gameObject.transform.GetChild(nChild).gameObject, bRecurseIntoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Mesh CreateNewEmptyMesh(MeshSimplify meshSimplify)
|
||||
{
|
||||
if(meshSimplify.m_originalMesh == null)
|
||||
{
|
||||
return new Mesh();
|
||||
}
|
||||
|
||||
Mesh meshOut = Mesh.Instantiate(meshSimplify.m_originalMesh);
|
||||
meshOut.Clear();
|
||||
return meshOut;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public void DisablePrefabUsage(bool bRecurseIntoChildren)
|
||||
{
|
||||
DisablePrefabUsageRecursive(this, this.gameObject, bRecurseIntoChildren);
|
||||
}
|
||||
|
||||
private static void DisablePrefabUsageRecursive(MeshSimplify root, GameObject gameObject, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null)
|
||||
{
|
||||
if (IsRootOrBelongsToTree(meshSimplify, root))
|
||||
{
|
||||
if (meshSimplify.m_simplifiedMesh)
|
||||
{
|
||||
if (UnityEditor.AssetDatabase.IsMainAsset(meshSimplify.m_simplifiedMesh) || UnityEditor.AssetDatabase.IsSubAsset(meshSimplify.m_simplifiedMesh))
|
||||
{
|
||||
Mesh newMesh = Instantiate(meshSimplify.m_simplifiedMesh) as Mesh;
|
||||
meshSimplify.m_simplifiedMesh = newMesh;
|
||||
}
|
||||
}
|
||||
|
||||
meshSimplify.m_strAssetPath = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
DisablePrefabUsageRecursive(root, gameObject.transform.GetChild(nChild).gameObject, bRecurseIntoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/MeshSimplify.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/MeshSimplify.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 100bcc9db4f7fc64e95ecc1abca8c97d
|
||||
timeCreated: 1438106980
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
378
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/MeshUniqueVertices.cs
vendored
Normal file
378
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/MeshUniqueVertices.cs
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UltimateGameTools
|
||||
{
|
||||
namespace MeshSimplifier
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that will take a Mesh as input and will build internal data to identify which vertices are repeated due to
|
||||
/// different vertex data (UV, vertex colors etc).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class MeshUniqueVertices
|
||||
{
|
||||
#region Public types
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public types
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// A list of vertex indices. We use this in order to be able to serialize a list of lists.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ListIndices
|
||||
{
|
||||
public ListIndices()
|
||||
{
|
||||
m_listIndices = new List<int>();
|
||||
}
|
||||
|
||||
public List<int> m_listIndices;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Our serializable version of Unity's BoneWeight
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SerializableBoneWeight
|
||||
{
|
||||
public SerializableBoneWeight(BoneWeight boneWeight)
|
||||
{
|
||||
_boneIndex0 = boneWeight.boneIndex0;
|
||||
_boneIndex1 = boneWeight.boneIndex1;
|
||||
_boneIndex2 = boneWeight.boneIndex2;
|
||||
_boneIndex3 = boneWeight.boneIndex3;
|
||||
|
||||
_boneWeight0 = boneWeight.weight0;
|
||||
_boneWeight1 = boneWeight.weight1;
|
||||
_boneWeight2 = boneWeight.weight2;
|
||||
_boneWeight3 = boneWeight.weight3;
|
||||
}
|
||||
|
||||
public BoneWeight ToBoneWeight()
|
||||
{
|
||||
BoneWeight boneWeight = new BoneWeight();
|
||||
|
||||
boneWeight.boneIndex0 = _boneIndex0;
|
||||
boneWeight.boneIndex1 = _boneIndex1;
|
||||
boneWeight.boneIndex2 = _boneIndex2;
|
||||
boneWeight.boneIndex3 = _boneIndex3;
|
||||
|
||||
boneWeight.weight0 = _boneWeight0;
|
||||
boneWeight.weight1 = _boneWeight1;
|
||||
boneWeight.weight2 = _boneWeight2;
|
||||
boneWeight.weight3 = _boneWeight3;
|
||||
|
||||
return boneWeight;
|
||||
}
|
||||
|
||||
public int _boneIndex0;
|
||||
public int _boneIndex1;
|
||||
public int _boneIndex2;
|
||||
public int _boneIndex3;
|
||||
|
||||
public float _boneWeight0;
|
||||
public float _boneWeight1;
|
||||
public float _boneWeight2;
|
||||
public float _boneWeight3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vertex that is has a unique position in space.
|
||||
/// </summary>
|
||||
public class UniqueVertex
|
||||
{
|
||||
// Overrides from Object
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
UniqueVertex uniqueVertex = obj as UniqueVertex;
|
||||
return (uniqueVertex.m_nFixedX == m_nFixedX) && (uniqueVertex.m_nFixedY == m_nFixedY) && (uniqueVertex.m_nFixedZ == m_nFixedZ);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_nFixedX + (m_nFixedY << 2) + (m_nFixedZ << 4);
|
||||
}
|
||||
|
||||
// Constructor
|
||||
|
||||
public UniqueVertex(Vector3 v3Vertex)
|
||||
{
|
||||
FromVertex(v3Vertex);
|
||||
}
|
||||
|
||||
// Public methods
|
||||
|
||||
public Vector3 ToVertex()
|
||||
{
|
||||
return new Vector3(FixedToCoord(m_nFixedX), FixedToCoord(m_nFixedY), FixedToCoord(m_nFixedZ));
|
||||
}
|
||||
|
||||
// Comparison operators
|
||||
|
||||
public static bool operator ==(UniqueVertex a, UniqueVertex b)
|
||||
{
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
public static bool operator !=(UniqueVertex a, UniqueVertex b)
|
||||
{
|
||||
return !a.Equals(b);
|
||||
}
|
||||
|
||||
// Private methods/vars
|
||||
|
||||
private void FromVertex(Vector3 vertex)
|
||||
{
|
||||
m_nFixedX = CoordToFixed(vertex.x);
|
||||
m_nFixedY = CoordToFixed(vertex.y);
|
||||
m_nFixedZ = CoordToFixed(vertex.z);
|
||||
}
|
||||
|
||||
private int CoordToFixed(float fCoord)
|
||||
{
|
||||
int nInteger = Mathf.FloorToInt(fCoord);
|
||||
int nRemainder = Mathf.FloorToInt((fCoord - nInteger) * fDecimalMultiplier);
|
||||
|
||||
return nInteger << 16 | nRemainder;
|
||||
}
|
||||
|
||||
private float FixedToCoord(int nFixed)
|
||||
{
|
||||
float fRemainder = (nFixed & 0xFFFF) / fDecimalMultiplier;
|
||||
float fInteger = nFixed >> 16;
|
||||
|
||||
return fInteger + fRemainder;
|
||||
}
|
||||
|
||||
// Private vars
|
||||
|
||||
private int m_nFixedX, m_nFixedY, m_nFixedZ;
|
||||
private const float fDecimalMultiplier = 100000.0f;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region Public properties
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public properties
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// For each submesh, a list of faces. ListIndices has 3 indices for each face.
|
||||
/// Each index is a vertex in ListVertices.
|
||||
/// </summary>
|
||||
public ListIndices[] SubmeshesFaceList
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_aFaceList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Our list of vertices. Vertices are unique, so no vertex shares the same position in space.
|
||||
/// </summary>
|
||||
public List<Vector3> ListVertices
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_listVertices;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Our list of vertices in world space.
|
||||
/// Vertices are unique, so no vertex shares the same position in space.
|
||||
/// </summary>
|
||||
public List<Vector3> ListVerticesWorld
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_listVerticesWorld;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Our list of vertex bone weights
|
||||
/// </summary>
|
||||
public List<SerializableBoneWeight> ListBoneWeights
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_listBoneWeights;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion // Public properties
|
||||
#region Public methods
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// Takes a Mesh as input and will build a new list of faces and vertices. The vertex list will
|
||||
/// have no vertices sharing position in 3D space. The input mesh may have them, since often
|
||||
/// a vertex will have different mapping coordinates for each of the faces that share it.
|
||||
/// </summary>
|
||||
/// <param name="sourceMesh"></param>
|
||||
/// <param name="av3VerticesWorld"</param>
|
||||
public void BuildData(Mesh sourceMesh, Vector3[] av3VerticesWorld)
|
||||
{
|
||||
Vector3[] av3Vertices = sourceMesh.vertices;
|
||||
BoneWeight[] aBoneWeights = sourceMesh.boneWeights;
|
||||
|
||||
Dictionary<UniqueVertex, RepeatedVertexList> dicUniqueVertex2RepeatedVertexList = new Dictionary<UniqueVertex, RepeatedVertexList>();
|
||||
|
||||
m_listVertices = new List<Vector3>();
|
||||
m_listVerticesWorld = new List<Vector3>();
|
||||
m_listBoneWeights = new List<SerializableBoneWeight>();
|
||||
m_aFaceList = new ListIndices[sourceMesh.subMeshCount];
|
||||
|
||||
for (int nSubMesh = 0; nSubMesh < sourceMesh.subMeshCount; nSubMesh++)
|
||||
{
|
||||
m_aFaceList[nSubMesh] = new ListIndices();
|
||||
int[] anFaces = sourceMesh.GetTriangles(nSubMesh);
|
||||
|
||||
for (int i = 0; i < anFaces.Length; i++)
|
||||
{
|
||||
UniqueVertex vertex = new UniqueVertex(av3Vertices[anFaces[i]]);
|
||||
|
||||
if (dicUniqueVertex2RepeatedVertexList.ContainsKey(vertex))
|
||||
{
|
||||
dicUniqueVertex2RepeatedVertexList[vertex].Add(new RepeatedVertex(i / 3, anFaces[i]));
|
||||
m_aFaceList[nSubMesh].m_listIndices.Add(dicUniqueVertex2RepeatedVertexList[vertex].UniqueIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
int nNewUniqueIndex = m_listVertices.Count;
|
||||
dicUniqueVertex2RepeatedVertexList.Add(vertex, new RepeatedVertexList(nNewUniqueIndex, new RepeatedVertex(i / 3, anFaces[i])));
|
||||
m_listVertices.Add(av3Vertices[anFaces[i]]);
|
||||
m_listVerticesWorld.Add(av3VerticesWorld[anFaces[i]]);
|
||||
m_aFaceList[nSubMesh].m_listIndices.Add(nNewUniqueIndex);
|
||||
|
||||
if(aBoneWeights != null && aBoneWeights.Length > 0)
|
||||
{
|
||||
m_listBoneWeights.Add(new SerializableBoneWeight(aBoneWeights[anFaces[i]]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Debug.Log("In: " + av3Vertices.Length + " vertices. Out: " + m_listVertices.Count + " vertices.");
|
||||
}
|
||||
|
||||
#endregion // Public methods
|
||||
#region Private types
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private types
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// Vertex that has the same position in space as another one, but different vertex data (UV, color...).
|
||||
/// </summary>
|
||||
private class RepeatedVertex
|
||||
{
|
||||
// Public properties
|
||||
|
||||
/// <summary>
|
||||
/// Face it belongs to. This will be the same index in the source mesh as in the internal created face list.
|
||||
/// </summary>
|
||||
public int FaceIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return _nFaceIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Position in the original vertex array.
|
||||
/// </summary>
|
||||
public int OriginalVertexIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return _nOriginalVertexIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Constructor
|
||||
|
||||
public RepeatedVertex(int nFaceIndex, int nOriginalVertexIndex)
|
||||
{
|
||||
_nFaceIndex = nFaceIndex;
|
||||
_nOriginalVertexIndex = nOriginalVertexIndex;
|
||||
}
|
||||
|
||||
// Private vars
|
||||
|
||||
private int _nFaceIndex;
|
||||
private int _nOriginalVertexIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of vertices that have the same position in space but different vertex data (UV, color...).
|
||||
/// </summary>
|
||||
private class RepeatedVertexList
|
||||
{
|
||||
// Public properties
|
||||
|
||||
/// <summary>
|
||||
/// Unique vertex index in our array for this list.
|
||||
/// </summary>
|
||||
public int UniqueIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_nUniqueIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Public methods
|
||||
|
||||
public RepeatedVertexList(int nUniqueIndex, RepeatedVertex repeatedVertex)
|
||||
{
|
||||
m_nUniqueIndex = nUniqueIndex;
|
||||
m_listRepeatedVertices = new List<RepeatedVertex>();
|
||||
m_listRepeatedVertices.Add(repeatedVertex);
|
||||
}
|
||||
|
||||
public void Add(RepeatedVertex repeatedVertex)
|
||||
{
|
||||
m_listRepeatedVertices.Add(repeatedVertex);
|
||||
}
|
||||
|
||||
// Private vars
|
||||
|
||||
private int m_nUniqueIndex;
|
||||
private List<RepeatedVertex> m_listRepeatedVertices;
|
||||
}
|
||||
|
||||
#endregion // Private types
|
||||
#region Private vars
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private vars
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
[SerializeField]
|
||||
private List<Vector3> m_listVertices;
|
||||
[SerializeField]
|
||||
private List<Vector3> m_listVerticesWorld;
|
||||
[SerializeField]
|
||||
private List<SerializableBoneWeight> m_listBoneWeights;
|
||||
[SerializeField]
|
||||
private ListIndices[] m_aFaceList;
|
||||
|
||||
#endregion // Private vars
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/MeshUniqueVertices.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/MeshUniqueVertices.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c9aa0aceed4b66242b713cf6b09e6a9f
|
||||
timeCreated: 1434653219
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
176
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/RuntimeMeshSimplifier.cs
vendored
Normal file
176
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/RuntimeMeshSimplifier.cs
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UltimateGameTools.MeshSimplifier;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(MeshSimplify))]
|
||||
public class RuntimeMeshSimplifier : MonoBehaviour
|
||||
{
|
||||
public string ProgressTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_strLastTitle;
|
||||
}
|
||||
}
|
||||
|
||||
public string ProgressMessage
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_strLastMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public int ProgressPercent
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_nLastProgress;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Finished
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_bFinished;
|
||||
}
|
||||
}
|
||||
|
||||
public void Simplify(float percent)
|
||||
{
|
||||
if (m_bFinished == false)
|
||||
{
|
||||
StartCoroutine(ComputeMeshWithVertices(Mathf.Clamp01(percent / 100.0f)));
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_selectedMeshSimplify = GetComponent<MeshSimplify>();
|
||||
|
||||
m_objectMaterials = new Dictionary<GameObject, Material[]>();
|
||||
AddMaterials(m_selectedMeshSimplify.gameObject, m_objectMaterials);
|
||||
|
||||
m_bFinished = false;
|
||||
}
|
||||
|
||||
private void AddMaterials(GameObject theGameObject, Dictionary<GameObject, Material[]> dicMaterials)
|
||||
{
|
||||
Renderer theRenderer = theGameObject.GetComponent<Renderer>();
|
||||
|
||||
if (theRenderer != null && theRenderer.sharedMaterials != null && (MeshSimplify.HasValidMeshData(theGameObject) || theGameObject.GetComponent<MeshSimplify>() != null))
|
||||
{
|
||||
dicMaterials.Add(theGameObject, theRenderer.sharedMaterials);
|
||||
}
|
||||
|
||||
if (m_selectedMeshSimplify.RecurseIntoChildren)
|
||||
{
|
||||
for (int i = 0; i < theGameObject.transform.childCount; i++)
|
||||
{
|
||||
AddMaterials(theGameObject.transform.GetChild(i).gameObject, dicMaterials);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Progress(string strTitle, string strMessage, float fT)
|
||||
{
|
||||
int nPercent = Mathf.RoundToInt(fT * 100.0f);
|
||||
|
||||
if (nPercent != m_nLastProgress || m_strLastTitle != strTitle || m_strLastMessage != strMessage)
|
||||
{
|
||||
m_strLastTitle = strTitle;
|
||||
m_strLastMessage = strMessage;
|
||||
m_nLastProgress = nPercent;
|
||||
|
||||
//Debug.Log(strTitle + " " + strMessage + " " + nPercent);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator ComputeMeshWithVertices(float fAmount)
|
||||
{
|
||||
Simplifier.CoroutineFrameMiliseconds = 20;
|
||||
|
||||
foreach (KeyValuePair<GameObject, Material[]> pair in m_objectMaterials)
|
||||
{
|
||||
MeshSimplify meshSimplify = pair.Key.GetComponent<MeshSimplify>();
|
||||
MeshFilter meshFilter = pair.Key.GetComponent<MeshFilter>();
|
||||
SkinnedMeshRenderer skin = pair.Key.GetComponent<SkinnedMeshRenderer>();
|
||||
|
||||
if(meshSimplify == null)
|
||||
{
|
||||
meshSimplify = pair.Key.AddComponent<MeshSimplify>();
|
||||
meshSimplify.m_meshSimplifyRoot = m_selectedMeshSimplify;
|
||||
m_selectedMeshSimplify.m_listDependentChildren.Add(meshSimplify);
|
||||
}
|
||||
|
||||
if(meshSimplify.MeshSimplifier == null)
|
||||
{
|
||||
meshSimplify.MeshSimplifier = meshSimplify.gameObject.AddComponent<Simplifier>();
|
||||
meshSimplify.MeshSimplifier.hideFlags = HideFlags.HideInInspector;
|
||||
meshSimplify.ConfigureSimplifier();
|
||||
}
|
||||
|
||||
if (meshSimplify && MeshSimplify.HasValidMeshData(pair.Key))
|
||||
{
|
||||
Mesh newMesh = null;
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
newMesh = Mesh.Instantiate(meshFilter.sharedMesh);
|
||||
}
|
||||
else if (skin != null)
|
||||
{
|
||||
newMesh = Mesh.Instantiate(skin.sharedMesh);
|
||||
}
|
||||
|
||||
if (meshSimplify.HasData() == false)
|
||||
{
|
||||
meshSimplify.GetMeshSimplifier().CoroutineEnded = false;
|
||||
|
||||
StartCoroutine(meshSimplify.GetMeshSimplifier().ProgressiveMesh(pair.Key, meshFilter != null ? meshFilter.sharedMesh : skin.sharedMesh, null, meshSimplify.name, Progress));
|
||||
|
||||
while (meshSimplify.GetMeshSimplifier().CoroutineEnded == false)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (meshSimplify.GetMeshSimplifier() != null)
|
||||
{
|
||||
meshSimplify.GetMeshSimplifier().CoroutineEnded = false;
|
||||
|
||||
StartCoroutine(meshSimplify.GetMeshSimplifier().ComputeMeshWithVertexCount(pair.Key, newMesh, Mathf.RoundToInt(fAmount * meshSimplify.GetMeshSimplifier().GetOriginalMeshUniqueVertexCount()), meshSimplify.name, Progress));
|
||||
|
||||
while (meshSimplify.GetMeshSimplifier().CoroutineEnded == false)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
meshFilter.mesh = newMesh;
|
||||
}
|
||||
else if (skin != null)
|
||||
{
|
||||
skin.sharedMesh = newMesh;
|
||||
}
|
||||
|
||||
meshSimplify.m_simplifiedMesh = newMesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_bFinished = true;
|
||||
}
|
||||
|
||||
private Dictionary<GameObject, Material[]> m_objectMaterials;
|
||||
private MeshSimplify m_selectedMeshSimplify;
|
||||
|
||||
private bool m_bFinished = false;
|
||||
private Mesh m_newMesh;
|
||||
private int m_nLastProgress = -1;
|
||||
private string m_strLastTitle = "";
|
||||
private string m_strLastMessage = "";
|
||||
}
|
||||
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/RuntimeMeshSimplifier.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/RuntimeMeshSimplifier.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10b6bfc6d6d946449bd6178082a26d5e
|
||||
timeCreated: 1496044654
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1490
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/Simplifier.cs
vendored
Normal file
1490
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/Simplifier.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/Simplifier.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts/Simplifier.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90d922b6196aab34697b544f28239ee2
|
||||
timeCreated: 1434653219
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user