111
This commit is contained in:
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Data.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Data.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 254d70a8b3d89324da256e5cffdd1daa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Data/Scripts.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Data/Scripts.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0aaa0eba67f86b4aade715580d29551
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
326
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Data/Scripts/SimplifyMeshPreview.cs
vendored
Normal file
326
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Data/Scripts/SimplifyMeshPreview.cs
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Threading;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UltimateGameTools.MeshSimplifier;
|
||||
|
||||
public class SimplifyMeshPreview : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public class ShowcaseObject
|
||||
{
|
||||
public MeshSimplify m_meshSimplify;
|
||||
public Vector3 m_position;
|
||||
public Vector3 m_angles;
|
||||
public Vector3 m_rotationAxis = Vector3.up;
|
||||
public string m_description;
|
||||
}
|
||||
|
||||
public ShowcaseObject[] ShowcaseObjects;
|
||||
public Material WireframeMaterial;
|
||||
public float MouseSensitvity = 0.3f;
|
||||
public float MouseReleaseSpeed = 3.0f;
|
||||
|
||||
void Start ()
|
||||
{
|
||||
if (ShowcaseObjects != null && ShowcaseObjects.Length > 0)
|
||||
{
|
||||
for (int i = 0; i < ShowcaseObjects.Length; i++)
|
||||
{
|
||||
ShowcaseObjects[i].m_description = ShowcaseObjects[i].m_description.Replace("\\n", Environment.NewLine);
|
||||
}
|
||||
|
||||
SetActiveObject(0);
|
||||
}
|
||||
|
||||
Simplifier.CoroutineFrameMiliseconds = 20;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if(Input.GetKeyDown(KeyCode.F1))
|
||||
{
|
||||
m_bGUIEnabled = !m_bGUIEnabled;
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.W))
|
||||
{
|
||||
m_bWireframe = !m_bWireframe;
|
||||
SetWireframe(m_bWireframe);
|
||||
}
|
||||
|
||||
if (m_selectedMeshSimplify != null)
|
||||
{
|
||||
if (Input.GetMouseButton(0) && Input.mousePosition.y > 100)
|
||||
{
|
||||
Vector3 v3Angles = ShowcaseObjects[m_nSelectedIndex].m_rotationAxis * -((Input.mousePosition.x - m_fLastMouseX) * MouseSensitvity);
|
||||
m_selectedMeshSimplify.transform.Rotate(v3Angles, Space.Self);
|
||||
}
|
||||
else if (Input.GetMouseButtonUp(0) && Input.mousePosition.y > 100)
|
||||
{
|
||||
m_fRotationSpeed = -(Input.mousePosition.x - m_fLastMouseX) * MouseReleaseSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 v3Angles = ShowcaseObjects[m_nSelectedIndex].m_rotationAxis * (m_fRotationSpeed * Time.deltaTime);
|
||||
m_selectedMeshSimplify.transform.Rotate(v3Angles, Space.Self);
|
||||
}
|
||||
}
|
||||
|
||||
m_fLastMouseX = Input.mousePosition.x;
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
// Exit menu
|
||||
|
||||
int BoxWidth = 150;
|
||||
int BoxHeight = 50;
|
||||
int MarginH = 20;
|
||||
int MarginV = 10;
|
||||
|
||||
Rect boxRect = new Rect((Screen.width / 2) - (BoxWidth / 2), 0, BoxWidth, BoxHeight);
|
||||
Rect areaRect = new Rect(boxRect.x + MarginH, boxRect.y + MarginV, BoxWidth - (MarginH * 2), BoxHeight - (MarginV * 2));
|
||||
//GUI.Box(boxRect, "");
|
||||
//GUI.Box(boxRect, "");
|
||||
GUILayout.BeginArea(areaRect);
|
||||
|
||||
if(GUILayout.Button("Exit"))
|
||||
{
|
||||
Application.Quit();
|
||||
}
|
||||
|
||||
GUILayout.EndArea();
|
||||
|
||||
// Main menu
|
||||
|
||||
if(m_bGUIEnabled == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int nWidth = 400;
|
||||
|
||||
if(ShowcaseObjects == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool bAllowInteract = true;
|
||||
|
||||
if (!string.IsNullOrEmpty(m_strLastTitle) && !string.IsNullOrEmpty(m_strLastMessage))
|
||||
{
|
||||
bAllowInteract = false;
|
||||
}
|
||||
|
||||
GUI.Box(new Rect(0, 0, nWidth + 10, 400), "");
|
||||
|
||||
GUILayout.Label("Select model:", GUILayout.Width(nWidth));
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
for (int i = 0; i < ShowcaseObjects.Length; i++)
|
||||
{
|
||||
if (GUILayout.Button(ShowcaseObjects[i].m_meshSimplify.name) && bAllowInteract)
|
||||
{
|
||||
if (m_selectedMeshSimplify != null)
|
||||
{
|
||||
DestroyImmediate(m_selectedMeshSimplify.gameObject);
|
||||
}
|
||||
|
||||
SetActiveObject(i);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (m_selectedMeshSimplify != null)
|
||||
{
|
||||
GUILayout.Space(20);
|
||||
GUILayout.Label(ShowcaseObjects[m_nSelectedIndex].m_description);
|
||||
GUILayout.Space(20);
|
||||
|
||||
GUI.changed = false;
|
||||
m_bWireframe = GUILayout.Toggle(m_bWireframe, "Show wireframe");
|
||||
|
||||
if (GUI.changed && m_selectedMeshSimplify != null)
|
||||
{
|
||||
SetWireframe(m_bWireframe);
|
||||
}
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
int nSimplifiedVertices = m_selectedMeshSimplify.GetSimplifiedVertexCount(true);
|
||||
int nTotalVertices = m_selectedMeshSimplify.GetOriginalVertexCount(true);
|
||||
|
||||
GUILayout.Label("Vertex count: " + nSimplifiedVertices + "/" + nTotalVertices + " " + (Mathf.RoundToInt(((float)nSimplifiedVertices / (float)nTotalVertices) * 100.0f).ToString() + "% from original"));
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
if (!string.IsNullOrEmpty(m_strLastTitle) && !string.IsNullOrEmpty(m_strLastMessage))
|
||||
{
|
||||
GUILayout.Label(m_strLastTitle + ": " + m_strLastMessage, GUILayout.MaxWidth(nWidth));
|
||||
GUI.color = Color.blue;
|
||||
|
||||
Rect lastRect = GUILayoutUtility.GetLastRect();
|
||||
GUI.Box(new Rect(10, lastRect.yMax + 5, 204, 24), "");
|
||||
GUI.Box(new Rect(12, lastRect.yMax + 7, m_nLastProgress * 2, 20), "");
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("Vertices: " + (m_fVertexAmount * 100.0f).ToString("0.00") + "%");
|
||||
m_fVertexAmount = GUILayout.HorizontalSlider(m_fVertexAmount, 0.0f, 1.0f, GUILayout.Width(200));
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Space(3);
|
||||
|
||||
if (GUILayout.Button("Compute simplified mesh", GUILayout.Width(200)))
|
||||
{
|
||||
StartCoroutine(ComputeMeshWithVertices(m_fVertexAmount));
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetActiveObject(int index)
|
||||
{
|
||||
m_nSelectedIndex = index;
|
||||
|
||||
MeshSimplify meshSimplify = Instantiate(ShowcaseObjects[index].m_meshSimplify);
|
||||
meshSimplify.transform.position = ShowcaseObjects[index].m_position;
|
||||
meshSimplify.transform.rotation = Quaternion.Euler(ShowcaseObjects[index].m_angles);
|
||||
|
||||
m_selectedMeshSimplify = meshSimplify;
|
||||
|
||||
m_objectMaterials = new Dictionary<GameObject, Material[]>();
|
||||
AddMaterials(meshSimplify.gameObject, m_objectMaterials);
|
||||
|
||||
m_bWireframe = false;
|
||||
}
|
||||
|
||||
private void AddMaterials(GameObject theGameObject, Dictionary<GameObject, Material[]> dicMaterials)
|
||||
{
|
||||
Renderer theRenderer = theGameObject.GetComponent<Renderer>();
|
||||
MeshSimplify meshSimplify = theGameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (theRenderer != null && theRenderer.sharedMaterials != null && meshSimplify != null)
|
||||
{
|
||||
dicMaterials.Add(theGameObject, theRenderer.sharedMaterials);
|
||||
}
|
||||
|
||||
for (int i = 0; i < theGameObject.transform.childCount; i++)
|
||||
{
|
||||
AddMaterials(theGameObject.transform.GetChild(i).gameObject, dicMaterials);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetWireframe(bool bEnabled)
|
||||
{
|
||||
m_bWireframe = bEnabled;
|
||||
|
||||
foreach (KeyValuePair<GameObject, Material[]> pair in m_objectMaterials)
|
||||
{
|
||||
Renderer theRenderer = pair.Key.GetComponent<Renderer>();
|
||||
|
||||
if (bEnabled)
|
||||
{
|
||||
Material[] materials = new Material[pair.Value.Length];
|
||||
|
||||
for (int i = 0; i < pair.Value.Length; i++)
|
||||
{
|
||||
materials[i] = WireframeMaterial;
|
||||
}
|
||||
|
||||
theRenderer.sharedMaterials = materials;
|
||||
}
|
||||
else
|
||||
{
|
||||
theRenderer.sharedMaterials = pair.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator ComputeMeshWithVertices(float fAmount)
|
||||
{
|
||||
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 && (meshFilter != null || skin != null))
|
||||
{
|
||||
Mesh newMesh = null;
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
newMesh = Mesh.Instantiate(meshFilter.sharedMesh);
|
||||
}
|
||||
else if (skin != null)
|
||||
{
|
||||
newMesh = Mesh.Instantiate(skin.sharedMesh);
|
||||
}
|
||||
|
||||
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_strLastTitle = "";
|
||||
m_strLastMessage = "";
|
||||
m_nLastProgress = 0;
|
||||
}
|
||||
|
||||
Dictionary<GameObject, Material[]> m_objectMaterials;
|
||||
MeshSimplify m_selectedMeshSimplify;
|
||||
int m_nSelectedIndex = -1;
|
||||
bool m_bWireframe;
|
||||
float m_fRotationSpeed = 10.0f;
|
||||
float m_fLastMouseX;
|
||||
|
||||
Mesh m_newMesh;
|
||||
int m_nLastProgress = -1;
|
||||
string m_strLastTitle = "";
|
||||
string m_strLastMessage = "";
|
||||
|
||||
float m_fVertexAmount = 1.0f;
|
||||
|
||||
bool m_bGUIEnabled = true;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17244aba0a90b4a4189405b3405f74ae
|
||||
timeCreated: 1438106980
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Editor.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Editor.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a596981819401047ad211da94723baa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
763
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Editor/MeshSimplifyEditor.cs
vendored
Normal file
763
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Editor/MeshSimplifyEditor.cs
vendored
Normal file
@@ -0,0 +1,763 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UltimateGameTools.MeshSimplifier;
|
||||
|
||||
[CustomEditor(typeof(MeshSimplify)), CanEditMultipleObjects]
|
||||
public class MeshSimplifyEditor : Editor
|
||||
{
|
||||
void Progress(string strTitle, string strMessage, float fT)
|
||||
{
|
||||
int nPercent = Mathf.RoundToInt(fT * 100.0f);
|
||||
|
||||
if(nPercent != s_nLastProgress || s_strLastTitle != strTitle || s_strLastMessage != strMessage)
|
||||
{
|
||||
s_strLastTitle = strTitle;
|
||||
s_strLastMessage = strMessage;
|
||||
s_nLastProgress = nPercent;
|
||||
|
||||
if(EditorUtility.DisplayCancelableProgressBar(strTitle, strMessage, fT))
|
||||
{
|
||||
Simplifier.Cancelled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
PropertyGenerateIncludeChildren = serializedObject.FindProperty("m_bGenerateIncludeChildren");
|
||||
PropertyEnablePrefabUsage = serializedObject.FindProperty("m_bEnablePrefabUsage");
|
||||
PropertyExpandRelevanceSpheres = serializedObject.FindProperty("m_bExpandRelevanceSpheres");
|
||||
PropertyRelevanceSpheres = serializedObject.FindProperty("m_aRelevanceSpheres");
|
||||
PropertyOverrideRootSettings = serializedObject.FindProperty("m_bOverrideRootSettings");
|
||||
PropertyVertexAmount = serializedObject.FindProperty("m_fVertexAmount");
|
||||
PropertyUseEdgeLength = serializedObject.FindProperty("m_bUseEdgeLength");
|
||||
PropertyUseCurvature = serializedObject.FindProperty("m_bUseCurvature");
|
||||
PropertyProtectTexture = serializedObject.FindProperty("m_bProtectTexture");
|
||||
PropertyLockBorder = serializedObject.FindProperty("m_bLockBorder");
|
||||
PropertyDataDirty = serializedObject.FindProperty("m_bDataDirty");
|
||||
PropertyExcludedFromTree = serializedObject.FindProperty("m_bExcludedFromTree");
|
||||
|
||||
m_bComputeMesh = false;
|
||||
m_bEnablePrefabUsage = false;
|
||||
m_bDisablePrefabUsage = false;
|
||||
m_bDeleteData = false;
|
||||
m_bRemoveFromTree = false;
|
||||
m_bSetupNewRelevanceSphere = false;
|
||||
|
||||
SetHideFlags();
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
if(m_bPreviewOriginalMesh)
|
||||
{
|
||||
foreach (Object targetObject in targets)
|
||||
{
|
||||
if (targetObject != null)
|
||||
{
|
||||
MeshSimplify meshSimplify = targetObject as MeshSimplify;
|
||||
meshSimplify.AssignSimplifiedMesh(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnSceneGUI()
|
||||
{
|
||||
MeshSimplify meshSimplify = target as MeshSimplify;
|
||||
|
||||
bool bDrawSpheres = true;
|
||||
|
||||
if (meshSimplify.m_meshSimplifyRoot != null)
|
||||
{
|
||||
if (meshSimplify.m_meshSimplifyRoot.m_bExpandRelevanceSpheres == false)
|
||||
{
|
||||
bDrawSpheres = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (meshSimplify.m_bExpandRelevanceSpheres == false)
|
||||
{
|
||||
bDrawSpheres = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (meshSimplify.m_aRelevanceSpheres != null && bDrawSpheres)
|
||||
{
|
||||
for (int nSphere = 0; nSphere < meshSimplify.m_aRelevanceSpheres.Length; nSphere++)
|
||||
{
|
||||
if (meshSimplify.m_aRelevanceSpheres[nSphere].m_bExpanded == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
RelevanceSphere relevanceSphere = meshSimplify.m_aRelevanceSpheres[nSphere] as RelevanceSphere;
|
||||
|
||||
if (Tools.current == Tool.Move)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Vector3 v3Position = Handles.PositionHandle(relevanceSphere.m_v3Position, Quaternion.Euler(relevanceSphere.m_v3Rotation));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(meshSimplify, "Move Relevance Sphere");
|
||||
relevanceSphere.m_v3Position = v3Position;
|
||||
meshSimplify.RestoreOriginalMesh(false, true);
|
||||
meshSimplify.SetDataDirty(true);
|
||||
EditorUtility.SetDirty(target);
|
||||
}
|
||||
}
|
||||
else if (Tools.current == Tool.Rotate)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Quaternion qRotation = Handles.RotationHandle(Quaternion.Euler(relevanceSphere.m_v3Rotation), relevanceSphere.m_v3Position);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(meshSimplify, "Rotate Relevance Sphere");
|
||||
relevanceSphere.m_v3Rotation = qRotation.eulerAngles;
|
||||
meshSimplify.RestoreOriginalMesh(false, true);
|
||||
meshSimplify.SetDataDirty(true);
|
||||
EditorUtility.SetDirty(target);
|
||||
}
|
||||
}
|
||||
else if (Tools.current == Tool.Scale)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Vector3 v3Scale = Handles.ScaleHandle(relevanceSphere.m_v3Scale, relevanceSphere.m_v3Position, Quaternion.Euler(relevanceSphere.m_v3Rotation), HandleUtility.GetHandleSize(relevanceSphere.m_v3Position) * 1.0f);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Undo.RecordObject(meshSimplify, "Scale Relevance Sphere");
|
||||
relevanceSphere.m_v3Scale = v3Scale;
|
||||
meshSimplify.RestoreOriginalMesh(false, true);
|
||||
meshSimplify.SetDataDirty(true);
|
||||
EditorUtility.SetDirty(target);
|
||||
}
|
||||
}
|
||||
|
||||
if(Event.current.type == EventType.Repaint)
|
||||
{
|
||||
Matrix4x4 mtxHandles = Handles.matrix;
|
||||
Handles.matrix = Matrix4x4.TRS(relevanceSphere.m_v3Position, Quaternion.Euler(relevanceSphere.m_v3Rotation), relevanceSphere.m_v3Scale);
|
||||
Handles.color = new Color(0.0f, 0.0f, 1.0f, 0.5f);
|
||||
Handles.SphereHandleCap(0, Vector3.zero, Quaternion.identity, 1.0f, EventType.Repaint);
|
||||
Handles.matrix = mtxHandles;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
MeshSimplify meshSimplify;
|
||||
|
||||
string strIncludeChildrenLabel = "Recurse Into Children";
|
||||
int nButtonWidth = 200;
|
||||
int nButtonWidthSmall = 130;
|
||||
|
||||
foreach (Object targetObject in targets)
|
||||
{
|
||||
meshSimplify = targetObject as MeshSimplify;
|
||||
|
||||
if (meshSimplify.m_meshSimplifyRoot != null && targets.Length > 1)
|
||||
{
|
||||
EditorGUILayout.HelpBox("One or more GameObjects of the selection is not a root MeshSimplify GameObject. Only root MeshSimplify GameObjects can be edited at the same time.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (targets.Length > 1)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Multiple selection", MessageType.Info);
|
||||
}
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
meshSimplify = target as MeshSimplify;
|
||||
|
||||
if (meshSimplify.m_meshSimplifyRoot == null)
|
||||
{
|
||||
EditorGUILayout.PropertyField(PropertyGenerateIncludeChildren, new GUIContent(strIncludeChildrenLabel, "If checked, we will traverse the whole GameObject's hierarchy looking for meshes"));
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(PropertyEnablePrefabUsage, new GUIContent("Enable Prefab Usage", "Will save the generated mesh assets to disk, so that this GameObject can be used as a prefab and be instantiated at runtime. Otherwise the mesh won't be available"));
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
if (PropertyEnablePrefabUsage.boolValue)
|
||||
{
|
||||
m_bEnablePrefabUsage = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bDisablePrefabUsage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PropertyExcludedFromTree.boolValue)
|
||||
{
|
||||
GUILayout.Label("Object has been excluded from mesh simplification.");
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("Child MeshSimplify GameObject depending on " + meshSimplify.m_meshSimplifyRoot.name);
|
||||
EditorGUILayout.PropertyField(PropertyOverrideRootSettings, new GUIContent("Override " + meshSimplify.m_meshSimplifyRoot.name + " settings", "Will allow to edit this object's own parameters, instead of inheriting those of the root Automatic LOD GameObject"));
|
||||
}
|
||||
}
|
||||
|
||||
if (meshSimplify.m_meshSimplifyRoot == null || (PropertyOverrideRootSettings.boolValue == true && PropertyExcludedFromTree.boolValue == false))
|
||||
{
|
||||
bool bIsOverriden = PropertyOverrideRootSettings.boolValue == true;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(PropertyUseEdgeLength, new GUIContent("Use Edge Length", "Will take edge length into consideration when simplifying the mesh. Edges with higher length will be more likely to be kept"));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
PropertyDataDirty.boolValue = true;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(PropertyUseCurvature, new GUIContent("Use Curvature", "Will take the angle between triangles into consideration. Edges with smaller angles between two triangles will be more likely to be kept when simplifying the mesh."));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
PropertyDataDirty.boolValue = true;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(PropertyProtectTexture, new GUIContent("Protect Texture", "Will try to keep mapping integrity during the process of mesh simplification"));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
PropertyDataDirty.boolValue = true;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(PropertyLockBorder, new GUIContent("Keep Borders", "Will try to keep those vertices that form an object's border"));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
PropertyDataDirty.boolValue = true;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
float fVertexAmount = EditorGUILayout.Slider(new GUIContent("Vertex %", "The percentage of vertices from the original mesh to keep when simplifying it"), PropertyVertexAmount.floatValue * 100.0f, 0.0f, 100.0f);
|
||||
PropertyVertexAmount.floatValue = Mathf.Clamp01(fVertexAmount / 100.0f);
|
||||
int nSimplifiedMeshVertexCount = meshSimplify.GetSimplifiedVertexCount(bIsOverriden == false);
|
||||
int nMeshVertexCount = meshSimplify.GetOriginalVertexCount(bIsOverriden == false);
|
||||
|
||||
EditorGUILayout.LabelField("Vertex count: " + nSimplifiedMeshVertexCount + "/" + nMeshVertexCount);
|
||||
|
||||
int nSimplifiedMeshTriangleCount = meshSimplify.GetSimplifiedTriangleCount(bIsOverriden == false);
|
||||
int nMeshTriangleCount = meshSimplify.GetOriginalTriangleCount(bIsOverriden == false);
|
||||
|
||||
EditorGUILayout.LabelField("Triangle count: " + nSimplifiedMeshTriangleCount + "/" + nMeshTriangleCount);
|
||||
|
||||
//EditorGUILayout.LabelField("Child nodes: " + (meshSimplify.m_listDependentChildren == null ? 0 : meshSimplify.m_listDependentChildren.Count));
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
m_bPreviewOriginalMesh = EditorGUILayout.Toggle(new GUIContent("Preview Original Mesh", "Allows to quickly switch between viewing the simplified mesh and the original mesh to check the reduction quality"), m_bPreviewOriginalMesh);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
if (m_bPreviewOriginalMesh)
|
||||
{
|
||||
meshSimplify.RestoreOriginalMesh(false, bIsOverriden == false);
|
||||
}
|
||||
else
|
||||
{
|
||||
meshSimplify.AssignSimplifiedMesh(bIsOverriden == false);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
if (meshSimplify.m_meshSimplifyRoot == null)
|
||||
{
|
||||
PropertyExpandRelevanceSpheres.boolValue = EditorGUILayout.Foldout(PropertyExpandRelevanceSpheres.boolValue, new GUIContent("Vertex Relevance Modifiers:"));
|
||||
|
||||
if (PropertyExpandRelevanceSpheres.boolValue)
|
||||
{
|
||||
EditorGUILayout.HelpBox("Use vertex relevance spheres to select which vertices should be preserved with more or less priority when simplifying the mesh.", MessageType.Info);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Add New Sphere", "Adds a new vertex relevance sphere"), GUILayout.Width(nButtonWidthSmall)))
|
||||
{
|
||||
PropertyRelevanceSpheres.InsertArrayElementAtIndex(0);
|
||||
PropertyDataDirty.boolValue = true;
|
||||
m_bSetupNewRelevanceSphere = true;
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
int nSphereToDelete = -1;
|
||||
|
||||
for (int i = 0; i < PropertyRelevanceSpheres.arraySize; i++)
|
||||
{
|
||||
SerializedProperty elementProperty = PropertyRelevanceSpheres.GetArrayElementAtIndex(i);
|
||||
|
||||
SerializedProperty elementExpanded = elementProperty.FindPropertyRelative("m_bExpanded");
|
||||
SerializedProperty elementPosition = elementProperty.FindPropertyRelative("m_v3Position");
|
||||
SerializedProperty elementRotation = elementProperty.FindPropertyRelative("m_v3Rotation");
|
||||
SerializedProperty elementScale = elementProperty.FindPropertyRelative("m_v3Scale");
|
||||
SerializedProperty elementRelevance = elementProperty.FindPropertyRelative("m_fRelevance");
|
||||
|
||||
elementExpanded.boolValue = EditorGUILayout.Foldout(elementExpanded.boolValue, new GUIContent("Sphere"));
|
||||
|
||||
if (elementExpanded.boolValue)
|
||||
{
|
||||
bool bWideMode = EditorGUIUtility.wideMode;
|
||||
|
||||
EditorGUIUtility.wideMode = true;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(elementPosition, new GUIContent("Position"));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
PropertyDataDirty.boolValue = true;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(elementRotation, new GUIContent("Rotation"));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
PropertyDataDirty.boolValue = true;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(elementScale, new GUIContent("Scale"));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
PropertyDataDirty.boolValue = true;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
elementRelevance.floatValue = EditorGUILayout.Slider(new GUIContent("Relevance", "Tells the simplification algorithm how relevant the vertices inside this sphere are. Default relevance is 0, use lower values to discard non important vertices, and higher values to keep them before others when simplifying the mesh"), elementRelevance.floatValue, -1.0f, 1.0f);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
PropertyDataDirty.boolValue = true;
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Remove Sphere", "Removes this simplification sphere"), GUILayout.Width(nButtonWidthSmall)))
|
||||
{
|
||||
nSphereToDelete = i;
|
||||
PropertyDataDirty.boolValue = true;
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUIUtility.wideMode = bWideMode;
|
||||
}
|
||||
}
|
||||
|
||||
if (nSphereToDelete >= 0)
|
||||
{
|
||||
PropertyRelevanceSpheres.DeleteArrayElementAtIndex(nSphereToDelete);
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
if (meshSimplify.m_meshSimplifyRoot == null || (PropertyOverrideRootSettings.boolValue == true && PropertyExcludedFromTree.boolValue == false))
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Compute mesh", "Starts the mesh simplification process and assigns the GameObject the new simplified mesh"), GUILayout.Width(nButtonWidth)))
|
||||
{
|
||||
m_bComputeMesh = true;
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Restore Original Mesh...", "Deletes the simplified data and restores the original mesh"), GUILayout.Width(nButtonWidth)))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Delete all data and restore original mesh?", "Are you sure you want to delete all data and restore the original mesh?", "Delete", "Cancel"))
|
||||
{
|
||||
m_bDeleteData = true;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
if (meshSimplify.m_meshSimplifyRoot != null && PropertyExcludedFromTree.boolValue == false)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Exclude from tree...", "Restores this GameObject's original mesh and excludes it from the mesh simplification tree"), GUILayout.Width(nButtonWidth)))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Remove from tree?", "Are you sure you want to restore this gameobject's mesh and exclude it from the tree?", "Remove", "Cancel"))
|
||||
{
|
||||
m_bRemoveFromTree = true;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
bool bRepaint = false;
|
||||
|
||||
if(m_bEnablePrefabUsage)
|
||||
{
|
||||
m_bEnablePrefabUsage = false;
|
||||
SaveMeshAssets();
|
||||
}
|
||||
|
||||
if(m_bDisablePrefabUsage)
|
||||
{
|
||||
m_bDisablePrefabUsage = false;
|
||||
|
||||
if (PropertyEnablePrefabUsage.boolValue == false)
|
||||
{
|
||||
foreach (Object targetObject in targets)
|
||||
{
|
||||
meshSimplify = targetObject as MeshSimplify;
|
||||
meshSimplify.DisablePrefabUsage(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bComputeMesh && Event.current.type == EventType.Repaint)
|
||||
{
|
||||
m_bComputeMesh = false;
|
||||
|
||||
Simplifier.Cancelled = false;
|
||||
|
||||
foreach (Object targetObject in targets)
|
||||
{
|
||||
meshSimplify = targetObject as MeshSimplify;
|
||||
|
||||
if (meshSimplify.HasData() == false)
|
||||
{
|
||||
if (PropertyGenerateIncludeChildren.boolValue == false)
|
||||
{
|
||||
if (MeshSimplify.HasValidMeshData(meshSimplify.gameObject) == false)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error", "Object " + meshSimplify.name + " has no MeshFilter nor Skinned Mesh to process. Please use the \"" + strIncludeChildrenLabel + "\" parameter if you want to process the whole " + meshSimplify.name + " hierarchy for meshes", "OK");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (meshSimplify.HasDataDirty() || meshSimplify.HasData() == false || meshSimplify.HasNonMeshSimplifyGameObjectsInTree())
|
||||
{
|
||||
meshSimplify.RestoreOriginalMesh(true, meshSimplify.m_meshSimplifyRoot == null);
|
||||
meshSimplify.ComputeData(meshSimplify.m_meshSimplifyRoot == null, Progress);
|
||||
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
meshSimplify.RestoreOriginalMesh(true, meshSimplify.m_meshSimplifyRoot == null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
meshSimplify.ComputeMesh(meshSimplify.m_meshSimplifyRoot == null, Progress);
|
||||
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
meshSimplify.AssignSimplifiedMesh(meshSimplify.m_meshSimplifyRoot == null);
|
||||
|
||||
if (meshSimplify.m_strAssetPath != null && meshSimplify.m_bEnablePrefabUsage)
|
||||
{
|
||||
SaveMeshAssets();
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError("Error generating mesh: " + e.Message + " Stack: " + e.StackTrace);
|
||||
EditorUtility.ClearProgressBar();
|
||||
Simplifier.Cancelled = false;
|
||||
}
|
||||
|
||||
Simplifier.Cancelled = false;
|
||||
}
|
||||
|
||||
bRepaint = true;
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
if (m_bDeleteData && Event.current.type == EventType.Repaint)
|
||||
{
|
||||
m_bDeleteData = false;
|
||||
|
||||
foreach (Object targetObject in targets)
|
||||
{
|
||||
meshSimplify = targetObject as MeshSimplify;
|
||||
meshSimplify.RestoreOriginalMesh(true, meshSimplify.m_meshSimplifyRoot == null);
|
||||
RemoveChildMeshSimplifyComponents(meshSimplify);
|
||||
}
|
||||
|
||||
bRepaint = true;
|
||||
}
|
||||
|
||||
if (m_bRemoveFromTree && Event.current.type == EventType.Repaint)
|
||||
{
|
||||
m_bRemoveFromTree = false;
|
||||
meshSimplify = target as MeshSimplify;
|
||||
meshSimplify.RemoveFromTree();
|
||||
|
||||
if (Application.isEditor && Application.isPlaying == false)
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(meshSimplify);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Object.Destroy(meshSimplify);
|
||||
}
|
||||
|
||||
bRepaint = true;
|
||||
}
|
||||
|
||||
if (m_bSetupNewRelevanceSphere)
|
||||
{
|
||||
m_bSetupNewRelevanceSphere = false;
|
||||
|
||||
foreach (Object targetObject in targets)
|
||||
{
|
||||
meshSimplify = targetObject as MeshSimplify;
|
||||
|
||||
if (meshSimplify.m_aRelevanceSpheres != null && meshSimplify.m_aRelevanceSpheres.Length > 0)
|
||||
{
|
||||
meshSimplify.m_aRelevanceSpheres[0].SetDefault(meshSimplify.transform, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bRepaint)
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveChildMeshSimplifyComponents(MeshSimplify meshSimplify)
|
||||
{
|
||||
RemoveChildMeshSimplifyComponentsRecursive(meshSimplify.gameObject, meshSimplify.gameObject, true);
|
||||
}
|
||||
|
||||
void RemoveChildMeshSimplifyComponentsRecursive(GameObject root, GameObject gameObject, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null && meshSimplify.m_meshSimplifyRoot != null)
|
||||
{
|
||||
if (Application.isEditor && Application.isPlaying == false)
|
||||
{
|
||||
UnityEngine.Object.DestroyImmediate(meshSimplify);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Object.Destroy(meshSimplify);
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
RemoveChildMeshSimplifyComponentsRecursive(root, gameObject.transform.GetChild(nChild).gameObject, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveMeshAssets()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (Object targetObject in targets)
|
||||
{
|
||||
MeshSimplify meshSimplify = targetObject as MeshSimplify;
|
||||
GameObject gameObject = meshSimplify.gameObject;
|
||||
|
||||
if (meshSimplify.m_meshSimplifyRoot == null && meshSimplify.m_bEnablePrefabUsage)
|
||||
{
|
||||
string strMeshAssetPath = meshSimplify.m_strAssetPath;
|
||||
|
||||
if (string.IsNullOrEmpty(strMeshAssetPath))
|
||||
{
|
||||
//Debug.Log("Showing file selection panel");
|
||||
|
||||
strMeshAssetPath = UnityEditor.EditorUtility.SaveFilePanelInProject("Save mesh asset(s)", "mesh_" + gameObject.name + gameObject.GetInstanceID().ToString() + ".asset", "asset", "Please enter a file name to save the mesh asset(s) to");
|
||||
|
||||
if (strMeshAssetPath.Length == 0)
|
||||
{
|
||||
//Debug.LogWarning("strMeshAssetPath.Length == 0. User cancelled?");
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Log("User selected " + strMeshAssetPath + " using panel.");
|
||||
|
||||
meshSimplify.m_strAssetPath = strMeshAssetPath;
|
||||
}
|
||||
|
||||
int nCounter = 0;
|
||||
|
||||
//Debug.Log("Saving files to " + strMeshAssetPath + ". Exists previously?: " + System.IO.File.Exists(strMeshAssetPath));
|
||||
SaveMeshAssetsRecursive(gameObject, gameObject, strMeshAssetPath, true, System.IO.File.Exists(strMeshAssetPath), ref nCounter);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError("Error saving mesh assets to disk: " + e.Message + " Stack: " + e.StackTrace);
|
||||
EditorUtility.ClearProgressBar();
|
||||
Simplifier.Cancelled = false;
|
||||
}
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
UnityEditor.AssetDatabase.Refresh();
|
||||
Simplifier.Cancelled = false;
|
||||
}
|
||||
|
||||
bool SaveMeshAssetsRecursive(GameObject root, GameObject gameObject, string strFile, bool bRecurseIntoChildren, bool bAssetAlreadyCreated, ref int nProgressElementsCounter)
|
||||
{
|
||||
if(gameObject == null || Simplifier.Cancelled)
|
||||
{
|
||||
return bAssetAlreadyCreated;
|
||||
}
|
||||
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify != null && meshSimplify.HasData() && (meshSimplify.m_meshSimplifyRoot == null || meshSimplify.m_meshSimplifyRoot.gameObject == root))
|
||||
{
|
||||
int nTotalProgressElements = meshSimplify.m_meshSimplifyRoot != null ? (meshSimplify.m_meshSimplifyRoot.m_listDependentChildren.Count + 1) : 1;
|
||||
|
||||
if (meshSimplify.m_simplifiedMesh != null && MeshSimplify.HasValidMeshData(meshSimplify.gameObject))
|
||||
{
|
||||
float fT = (float)nProgressElementsCounter / (float)nTotalProgressElements;
|
||||
Progress("Saving meshes to asset file", meshSimplify.name, fT);
|
||||
|
||||
if (Simplifier.Cancelled)
|
||||
{
|
||||
return bAssetAlreadyCreated;
|
||||
}
|
||||
|
||||
if (bAssetAlreadyCreated == false && UnityEditor.AssetDatabase.Contains(meshSimplify.m_simplifiedMesh) == false)
|
||||
{
|
||||
//Debug.Log("Creating asset " + meshSimplify.m_simplifiedMesh.name);
|
||||
|
||||
UnityEditor.AssetDatabase.CreateAsset(meshSimplify.m_simplifiedMesh, strFile);
|
||||
bAssetAlreadyCreated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UnityEditor.AssetDatabase.Contains(meshSimplify.m_simplifiedMesh) == false)
|
||||
{
|
||||
//Debug.Log("Adding asset " + meshSimplify.m_simplifiedMesh.name);
|
||||
|
||||
UnityEditor.AssetDatabase.AddObjectToAsset(meshSimplify.m_simplifiedMesh, strFile);
|
||||
UnityEditor.AssetDatabase.ImportAsset(UnityEditor.AssetDatabase.GetAssetPath(meshSimplify.m_simplifiedMesh));
|
||||
}
|
||||
}
|
||||
|
||||
nProgressElementsCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
bAssetAlreadyCreated = SaveMeshAssetsRecursive(root, gameObject.transform.GetChild(nChild).gameObject, strFile, bRecurseIntoChildren, bAssetAlreadyCreated, ref nProgressElementsCounter);
|
||||
}
|
||||
}
|
||||
|
||||
return bAssetAlreadyCreated;
|
||||
}
|
||||
|
||||
void SetHideFlags()
|
||||
{
|
||||
foreach (Object targetObject in targets)
|
||||
{
|
||||
MeshSimplify meshSimplify = targetObject as MeshSimplify;
|
||||
|
||||
if (meshSimplify.m_meshSimplifyRoot == null)
|
||||
{
|
||||
SetHideFlagsRecursive(meshSimplify.gameObject, meshSimplify.gameObject, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetHideFlagsRecursive(GameObject root, GameObject gameObject, bool bRecurseIntoChildren)
|
||||
{
|
||||
MeshSimplify meshSimplify = gameObject.GetComponent<MeshSimplify>();
|
||||
|
||||
if (meshSimplify && meshSimplify.GetMeshSimplifier())
|
||||
{
|
||||
meshSimplify.GetMeshSimplifier().hideFlags = HideFlags.HideInInspector;
|
||||
}
|
||||
|
||||
if (bRecurseIntoChildren)
|
||||
{
|
||||
for (int nChild = 0; nChild < gameObject.transform.childCount; nChild++)
|
||||
{
|
||||
SetHideFlagsRecursive(root, gameObject.transform.GetChild(nChild).gameObject, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool m_bComputeMesh = false;
|
||||
bool m_bEnablePrefabUsage = false;
|
||||
bool m_bDisablePrefabUsage = false;
|
||||
bool m_bDeleteData = false;
|
||||
bool m_bRemoveFromTree = false;
|
||||
bool m_bSetupNewRelevanceSphere = false;
|
||||
|
||||
bool m_bPreviewOriginalMesh = false;
|
||||
|
||||
SerializedProperty PropertyGenerateIncludeChildren;
|
||||
SerializedProperty PropertyEnablePrefabUsage;
|
||||
SerializedProperty PropertyExpandRelevanceSpheres;
|
||||
SerializedProperty PropertyRelevanceSpheres;
|
||||
SerializedProperty PropertyOverrideRootSettings;
|
||||
SerializedProperty PropertyVertexAmount;
|
||||
SerializedProperty PropertyUseEdgeLength;
|
||||
SerializedProperty PropertyUseCurvature;
|
||||
SerializedProperty PropertyProtectTexture;
|
||||
SerializedProperty PropertyLockBorder;
|
||||
SerializedProperty PropertyDataDirty;
|
||||
SerializedProperty PropertyExcludedFromTree;
|
||||
|
||||
static int s_nLastProgress = -1;
|
||||
static string s_strLastTitle = "";
|
||||
static string s_strLastMessage = "";
|
||||
}
|
||||
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Editor/MeshSimplifyEditor.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Editor/MeshSimplifyEditor.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a52cb74794833b64492fa4b27f8cb797
|
||||
timeCreated: 1438106980
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify/Scripts.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef0e28345212fa344986b5be580ae95c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
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