Files
VR-WuKong/Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODSampleLODScene.cs
2025-11-14 18:44:06 +08:00

259 lines
6.6 KiB
C#

using System;
using UnityEngine;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using UltimateGameTools.MeshSimplifier;
public class LODSampleLODScene : MonoBehaviour
{
[Serializable]
public class SceneCamera
{
public Camera m_camera;
public float m_near;
public float m_far;
[HideInInspector]
public Vector3 m_v3InitialCameraPosition;
[HideInInspector]
public Vector3 m_v3ViewDir;
}
public SceneCamera[] SceneCameras;
public Material WireframeMaterial;
void Start ()
{
// Enumerate all our objects with automatic LOD components
AutomaticLOD[] automaticLODObjects = FindObjectsOfType<AutomaticLOD>();
m_sceneLODObjects = new List<AutomaticLOD>();
m_objectMaterials = new Dictionary<GameObject, Material[]>();
m_nMaxLODLevels = 0;
foreach (AutomaticLOD automaticLOD in automaticLODObjects)
{
if (automaticLOD.IsRootAutomaticLOD())
{
m_sceneLODObjects.Add(automaticLOD);
if (automaticLOD.GetLODLevelCount() > m_nMaxLODLevels)
{
m_nMaxLODLevels = automaticLOD.GetLODLevelCount();
}
AddMaterials(automaticLOD.gameObject, m_objectMaterials);
}
}
// Setup camera
if (SceneCameras != null && SceneCameras.Length > 0)
{
foreach(SceneCamera sceneCamera in SceneCameras)
{
sceneCamera.m_v3InitialCameraPosition = sceneCamera.m_camera.transform.position;
sceneCamera.m_v3ViewDir = sceneCamera.m_camera.transform.forward;
}
SetActiveCamera(0);
}
m_bWireframe = false;
}
void Update()
{
m_nCamMode = 0;
if(Input.GetKey(KeyCode.I))
{
m_nCamMode = 1;
}
else if (Input.GetKey(KeyCode.O))
{
m_nCamMode = -1;
}
if (m_nCamMode != 0)
{
m_fCurrentDistanceSlider -= Time.deltaTime * 0.1f * m_nCamMode;
m_fCurrentDistanceSlider = Mathf.Clamp01(m_fCurrentDistanceSlider);
UpdateCamera(m_fCurrentDistanceSlider);
}
if (Input.GetKeyDown(KeyCode.W))
{
m_bWireframe = !m_bWireframe;
SetWireframe(m_bWireframe);
}
}
void OnGUI()
{
int nWidth = 400;
if(SceneCameras == null)
{
return;
}
if (SceneCameras.Length == 0)
{
return;
}
GUI.Box(new Rect(0, 0, nWidth + 10, 260), "");
GUILayout.Space(20);
GUILayout.Label("Select camera:", GUILayout.Width(nWidth));
GUILayout.BeginHorizontal();
for (int i = 0; i < SceneCameras.Length; i++)
{
if (GUILayout.Button(SceneCameras[i].m_camera.name))
{
SetActiveCamera(i);
}
}
GUILayout.EndHorizontal();
GUILayout.Label("Camera distance:", GUILayout.Width(nWidth));
GUI.changed = false;
m_fCurrentDistanceSlider = GUILayout.HorizontalSlider(m_fCurrentDistanceSlider, 0.0f, 1.0f);
if (GUI.changed)
{
UpdateCamera(m_fCurrentDistanceSlider);
}
GUI.changed = false;
m_bWireframe = GUILayout.Toggle(m_bWireframe, "Show wireframe");
if (GUI.changed)
{
SetWireframe(m_bWireframe);
}
GUILayout.Space(20);
GUILayout.Label("Select LOD:");
GUILayout.BeginHorizontal();
if (GUILayout.Button("Automatic LOD"))
{
foreach(AutomaticLOD automaticLOD in m_sceneLODObjects)
{
automaticLOD.SetAutomaticCameraLODSwitch(true);
}
}
for (int i = 0; i < m_nMaxLODLevels; i++)
{
if (GUILayout.Button("LOD " + i))
{
foreach(AutomaticLOD automaticLOD in m_sceneLODObjects)
{
automaticLOD.SetAutomaticCameraLODSwitch(false);
automaticLOD.SwitchToLOD(i, true);
}
}
}
GUILayout.EndHorizontal();
GUILayout.Space(20);
int nLODVertexCount = 0;
int nTotalVertexCount = 0;
foreach(AutomaticLOD automaticLOD in m_sceneLODObjects)
{
nLODVertexCount += automaticLOD.GetCurrentVertexCount(true);
nTotalVertexCount += automaticLOD.GetOriginalVertexCount(true);
}
GUILayout.Label("Vertex count: " + nLODVertexCount + "/" + nTotalVertexCount + " " + Mathf.RoundToInt(100.0f * ((float)nLODVertexCount / (float)nTotalVertexCount)).ToString() + "%");
GUILayout.Space(20);
}
private void SetActiveCamera(int index)
{
foreach (SceneCamera sceneCamera in SceneCameras)
{
sceneCamera.m_camera.gameObject.SetActive(false);
}
m_selectedCamera = SceneCameras[index];
m_selectedCamera.m_camera.gameObject.SetActive(true);
m_selectedCamera.m_camera.transform.position = m_selectedCamera.m_v3InitialCameraPosition;
m_fCurrentDistanceSlider = m_selectedCamera.m_near / (m_selectedCamera.m_near - m_selectedCamera.m_far);
}
private void UpdateCamera(float fPos)
{
Vector3 v3Position = Vector3.Lerp(m_selectedCamera.m_v3InitialCameraPosition + (m_selectedCamera.m_v3ViewDir * m_selectedCamera.m_near),
m_selectedCamera.m_v3InitialCameraPosition + (m_selectedCamera.m_v3ViewDir * m_selectedCamera.m_far),
fPos);
m_selectedCamera.m_camera.transform.position = v3Position;
}
private void AddMaterials(GameObject theGameObject, Dictionary<GameObject, Material[]> dicMaterials)
{
Renderer theRenderer = theGameObject.GetComponent<Renderer>();
AutomaticLOD automaticLOD = theGameObject.GetComponent<AutomaticLOD>();
if (theRenderer != null && theRenderer.sharedMaterials != null && automaticLOD != null && automaticLOD != 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;
}
}
}
Dictionary<GameObject, Material[]> m_objectMaterials;
SceneCamera m_selectedCamera;
bool m_bWireframe;
List<AutomaticLOD> m_sceneLODObjects;
int m_nMaxLODLevels;
float m_fCurrentDistanceSlider;
int m_nCamMode = 0; // -1 = zoom out, 1 = zoom in
}