111
This commit is contained in:
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 534900b83d731e447a8abe406cb616b6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e46ea01a7996344eb0beb007193626a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Environment.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Environment.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45e9a2dc58c15a34a8bc8297ebdc8c69
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Environment/Water.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Environment/Water.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55c30f06c41a86348af15276b2f621c5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Environment/Water/Water.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Environment/Water/Water.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: adeae27536c26f349969271f27c1bdb8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31e9cb45329e9504aa7db1c06e069a34
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.Water
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(WaterBase))]
|
||||
public class Displace : MonoBehaviour
|
||||
{
|
||||
public void Awake()
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
OnEnable();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnDisable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
Shader.EnableKeyword("WATER_VERTEX_DISPLACEMENT_ON");
|
||||
Shader.DisableKeyword("WATER_VERTEX_DISPLACEMENT_OFF");
|
||||
}
|
||||
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
Shader.EnableKeyword("WATER_VERTEX_DISPLACEMENT_OFF");
|
||||
Shader.DisableKeyword("WATER_VERTEX_DISPLACEMENT_ON");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c62b7d87755b447919138e67f8e22e0c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.Water
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(WaterBase))]
|
||||
public class GerstnerDisplace : Displace { }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42e7f46d0e5a84171a3909479c1646ba
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.Water
|
||||
{
|
||||
public class MeshContainer
|
||||
{
|
||||
public Mesh mesh;
|
||||
public Vector3[] vertices;
|
||||
public Vector3[] normals;
|
||||
|
||||
|
||||
public MeshContainer(Mesh m)
|
||||
{
|
||||
mesh = m;
|
||||
vertices = m.vertices;
|
||||
normals = m.normals;
|
||||
}
|
||||
|
||||
|
||||
public void Update()
|
||||
{
|
||||
mesh.vertices = vertices;
|
||||
mesh.normals = normals;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 951d74f7d57bed84cb623c62436bd064
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,284 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.Water
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(WaterBase))]
|
||||
public class PlanarReflection : MonoBehaviour
|
||||
{
|
||||
public LayerMask reflectionMask;
|
||||
public bool reflectSkybox = false;
|
||||
public Color clearColor = Color.grey;
|
||||
public String reflectionSampler = "_ReflectionTex";
|
||||
public float clipPlaneOffset = 0.07F;
|
||||
|
||||
|
||||
Vector3 m_Oldpos;
|
||||
Camera m_ReflectionCamera;
|
||||
Material m_SharedMaterial;
|
||||
Dictionary<Camera, bool> m_HelperCameras;
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
m_SharedMaterial = ((WaterBase)gameObject.GetComponent(typeof(WaterBase))).sharedMaterial;
|
||||
}
|
||||
|
||||
|
||||
Camera CreateReflectionCameraFor(Camera cam)
|
||||
{
|
||||
String reflName = gameObject.name + "Reflection" + cam.name;
|
||||
GameObject go = GameObject.Find(reflName);
|
||||
|
||||
if (!go)
|
||||
{
|
||||
go = new GameObject(reflName, typeof(Camera));
|
||||
}
|
||||
if (!go.GetComponent(typeof(Camera)))
|
||||
{
|
||||
go.AddComponent(typeof(Camera));
|
||||
}
|
||||
Camera reflectCamera = go.GetComponent<Camera>();
|
||||
|
||||
reflectCamera.backgroundColor = clearColor;
|
||||
reflectCamera.clearFlags = reflectSkybox ? CameraClearFlags.Skybox : CameraClearFlags.SolidColor;
|
||||
|
||||
SetStandardCameraParameter(reflectCamera, reflectionMask);
|
||||
|
||||
if (!reflectCamera.targetTexture)
|
||||
{
|
||||
reflectCamera.targetTexture = CreateTextureFor(cam);
|
||||
}
|
||||
|
||||
return reflectCamera;
|
||||
}
|
||||
|
||||
|
||||
void SetStandardCameraParameter(Camera cam, LayerMask mask)
|
||||
{
|
||||
cam.cullingMask = mask & ~(1 << LayerMask.NameToLayer("Water"));
|
||||
cam.backgroundColor = Color.black;
|
||||
cam.enabled = false;
|
||||
}
|
||||
|
||||
|
||||
RenderTexture CreateTextureFor(Camera cam)
|
||||
{
|
||||
RenderTexture rt = new RenderTexture(Mathf.FloorToInt(cam.pixelWidth * 0.5F),
|
||||
Mathf.FloorToInt(cam.pixelHeight * 0.5F), 24);
|
||||
rt.hideFlags = HideFlags.DontSave;
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
public void RenderHelpCameras(Camera currentCam)
|
||||
{
|
||||
if (null == m_HelperCameras)
|
||||
{
|
||||
m_HelperCameras = new Dictionary<Camera, bool>();
|
||||
}
|
||||
|
||||
if (!m_HelperCameras.ContainsKey(currentCam))
|
||||
{
|
||||
m_HelperCameras.Add(currentCam, false);
|
||||
}
|
||||
if (m_HelperCameras[currentCam])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_ReflectionCamera)
|
||||
{
|
||||
m_ReflectionCamera = CreateReflectionCameraFor(currentCam);
|
||||
}
|
||||
|
||||
RenderReflectionFor(currentCam, m_ReflectionCamera);
|
||||
|
||||
m_HelperCameras[currentCam] = true;
|
||||
}
|
||||
|
||||
|
||||
public void LateUpdate()
|
||||
{
|
||||
if (null != m_HelperCameras)
|
||||
{
|
||||
m_HelperCameras.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void WaterTileBeingRendered(Transform tr, Camera currentCam)
|
||||
{
|
||||
RenderHelpCameras(currentCam);
|
||||
|
||||
if (m_ReflectionCamera && m_SharedMaterial)
|
||||
{
|
||||
m_SharedMaterial.SetTexture(reflectionSampler, m_ReflectionCamera.targetTexture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
Shader.EnableKeyword("WATER_REFLECTIVE");
|
||||
Shader.DisableKeyword("WATER_SIMPLE");
|
||||
}
|
||||
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
Shader.EnableKeyword("WATER_SIMPLE");
|
||||
Shader.DisableKeyword("WATER_REFLECTIVE");
|
||||
}
|
||||
|
||||
|
||||
void RenderReflectionFor(Camera cam, Camera reflectCamera)
|
||||
{
|
||||
if (!reflectCamera)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_SharedMaterial && !m_SharedMaterial.HasProperty(reflectionSampler))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
reflectCamera.cullingMask = reflectionMask & ~(1 << LayerMask.NameToLayer("Water"));
|
||||
|
||||
SaneCameraSettings(reflectCamera);
|
||||
|
||||
reflectCamera.backgroundColor = clearColor;
|
||||
reflectCamera.clearFlags = reflectSkybox ? CameraClearFlags.Skybox : CameraClearFlags.SolidColor;
|
||||
if (reflectSkybox)
|
||||
{
|
||||
if (cam.gameObject.GetComponent(typeof(Skybox)))
|
||||
{
|
||||
Skybox sb = (Skybox)reflectCamera.gameObject.GetComponent(typeof(Skybox));
|
||||
if (!sb)
|
||||
{
|
||||
sb = (Skybox)reflectCamera.gameObject.AddComponent(typeof(Skybox));
|
||||
}
|
||||
sb.material = ((Skybox)cam.GetComponent(typeof(Skybox))).material;
|
||||
}
|
||||
}
|
||||
|
||||
GL.invertCulling = true;
|
||||
|
||||
Transform reflectiveSurface = transform; //waterHeight;
|
||||
|
||||
Vector3 eulerA = cam.transform.eulerAngles;
|
||||
|
||||
reflectCamera.transform.eulerAngles = new Vector3(-eulerA.x, eulerA.y, eulerA.z);
|
||||
reflectCamera.transform.position = cam.transform.position;
|
||||
|
||||
Vector3 pos = reflectiveSurface.transform.position;
|
||||
pos.y = reflectiveSurface.position.y;
|
||||
Vector3 normal = reflectiveSurface.transform.up;
|
||||
float d = -Vector3.Dot(normal, pos) - clipPlaneOffset;
|
||||
Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d);
|
||||
|
||||
Matrix4x4 reflection = Matrix4x4.zero;
|
||||
reflection = CalculateReflectionMatrix(reflection, reflectionPlane);
|
||||
m_Oldpos = cam.transform.position;
|
||||
Vector3 newpos = reflection.MultiplyPoint(m_Oldpos);
|
||||
|
||||
reflectCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;
|
||||
|
||||
Vector4 clipPlane = CameraSpacePlane(reflectCamera, pos, normal, 1.0f);
|
||||
|
||||
Matrix4x4 projection = cam.projectionMatrix;
|
||||
projection = CalculateObliqueMatrix(projection, clipPlane);
|
||||
reflectCamera.projectionMatrix = projection;
|
||||
|
||||
reflectCamera.transform.position = newpos;
|
||||
Vector3 euler = cam.transform.eulerAngles;
|
||||
reflectCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z);
|
||||
|
||||
reflectCamera.Render();
|
||||
|
||||
GL.invertCulling = false;
|
||||
}
|
||||
|
||||
|
||||
void SaneCameraSettings(Camera helperCam)
|
||||
{
|
||||
helperCam.depthTextureMode = DepthTextureMode.None;
|
||||
helperCam.backgroundColor = Color.black;
|
||||
helperCam.clearFlags = CameraClearFlags.SolidColor;
|
||||
helperCam.renderingPath = RenderingPath.Forward;
|
||||
}
|
||||
|
||||
|
||||
static Matrix4x4 CalculateObliqueMatrix(Matrix4x4 projection, Vector4 clipPlane)
|
||||
{
|
||||
Vector4 q = projection.inverse * new Vector4(
|
||||
Sgn(clipPlane.x),
|
||||
Sgn(clipPlane.y),
|
||||
1.0F,
|
||||
1.0F
|
||||
);
|
||||
Vector4 c = clipPlane * (2.0F / (Vector4.Dot(clipPlane, q)));
|
||||
// third row = clip plane - fourth row
|
||||
projection[2] = c.x - projection[3];
|
||||
projection[6] = c.y - projection[7];
|
||||
projection[10] = c.z - projection[11];
|
||||
projection[14] = c.w - projection[15];
|
||||
|
||||
return projection;
|
||||
}
|
||||
|
||||
|
||||
static Matrix4x4 CalculateReflectionMatrix(Matrix4x4 reflectionMat, Vector4 plane)
|
||||
{
|
||||
reflectionMat.m00 = (1.0F - 2.0F * plane[0] * plane[0]);
|
||||
reflectionMat.m01 = (- 2.0F * plane[0] * plane[1]);
|
||||
reflectionMat.m02 = (- 2.0F * plane[0] * plane[2]);
|
||||
reflectionMat.m03 = (- 2.0F * plane[3] * plane[0]);
|
||||
|
||||
reflectionMat.m10 = (- 2.0F * plane[1] * plane[0]);
|
||||
reflectionMat.m11 = (1.0F - 2.0F * plane[1] * plane[1]);
|
||||
reflectionMat.m12 = (- 2.0F * plane[1] * plane[2]);
|
||||
reflectionMat.m13 = (- 2.0F * plane[3] * plane[1]);
|
||||
|
||||
reflectionMat.m20 = (- 2.0F * plane[2] * plane[0]);
|
||||
reflectionMat.m21 = (- 2.0F * plane[2] * plane[1]);
|
||||
reflectionMat.m22 = (1.0F - 2.0F * plane[2] * plane[2]);
|
||||
reflectionMat.m23 = (- 2.0F * plane[3] * plane[2]);
|
||||
|
||||
reflectionMat.m30 = 0.0F;
|
||||
reflectionMat.m31 = 0.0F;
|
||||
reflectionMat.m32 = 0.0F;
|
||||
reflectionMat.m33 = 1.0F;
|
||||
|
||||
return reflectionMat;
|
||||
}
|
||||
|
||||
|
||||
static float Sgn(float a)
|
||||
{
|
||||
if (a > 0.0F)
|
||||
{
|
||||
return 1.0F;
|
||||
}
|
||||
if (a < 0.0F)
|
||||
{
|
||||
return -1.0F;
|
||||
}
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
|
||||
Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign)
|
||||
{
|
||||
Vector3 offsetPos = pos + normal * clipPlaneOffset;
|
||||
Matrix4x4 m = cam.worldToCameraMatrix;
|
||||
Vector3 cpos = m.MultiplyPoint(offsetPos);
|
||||
Vector3 cnormal = m.MultiplyVector(normal).normalized * sideSign;
|
||||
|
||||
return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4185bc77c7194462ca3b1097ef4a5de0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.Water
|
||||
{
|
||||
[RequireComponent(typeof(WaterBase))]
|
||||
[ExecuteInEditMode]
|
||||
public class SpecularLighting : MonoBehaviour
|
||||
{
|
||||
public Transform specularLight;
|
||||
private WaterBase m_WaterBase;
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
m_WaterBase = (WaterBase)gameObject.GetComponent(typeof(WaterBase));
|
||||
}
|
||||
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (!m_WaterBase)
|
||||
{
|
||||
m_WaterBase = (WaterBase)gameObject.GetComponent(typeof(WaterBase));
|
||||
}
|
||||
|
||||
if (specularLight && m_WaterBase.sharedMaterial)
|
||||
{
|
||||
m_WaterBase.sharedMaterial.SetVector("_WorldLightDir", specularLight.transform.forward);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de2ab2b9ac93bb544b9552e49030371b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,396 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.Water
|
||||
{
|
||||
[ExecuteInEditMode] // Make water live-update even when not in play mode
|
||||
public class Water : MonoBehaviour
|
||||
{
|
||||
public enum WaterMode
|
||||
{
|
||||
Simple = 0,
|
||||
Reflective = 1,
|
||||
Refractive = 2,
|
||||
};
|
||||
|
||||
|
||||
public WaterMode waterMode = WaterMode.Refractive;
|
||||
public bool disablePixelLights = true;
|
||||
public int textureSize = 256;
|
||||
public float clipPlaneOffset = 0.07f;
|
||||
public LayerMask reflectLayers = -1;
|
||||
public LayerMask refractLayers = -1;
|
||||
|
||||
|
||||
private Dictionary<Camera, Camera> m_ReflectionCameras = new Dictionary<Camera, Camera>(); // Camera -> Camera table
|
||||
private Dictionary<Camera, Camera> m_RefractionCameras = new Dictionary<Camera, Camera>(); // Camera -> Camera table
|
||||
private RenderTexture m_ReflectionTexture;
|
||||
private RenderTexture m_RefractionTexture;
|
||||
private WaterMode m_HardwareWaterSupport = WaterMode.Refractive;
|
||||
private int m_OldReflectionTextureSize;
|
||||
private int m_OldRefractionTextureSize;
|
||||
private static bool s_InsideWater;
|
||||
|
||||
|
||||
// This is called when it's known that the object will be rendered by some
|
||||
// camera. We render reflections / refractions and do other updates here.
|
||||
// Because the script executes in edit mode, reflections for the scene view
|
||||
// camera will just work!
|
||||
public void OnWillRenderObject()
|
||||
{
|
||||
if (!enabled || !GetComponent<Renderer>() || !GetComponent<Renderer>().sharedMaterial ||
|
||||
!GetComponent<Renderer>().enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Camera cam = Camera.current;
|
||||
if (!cam)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Safeguard from recursive water reflections.
|
||||
if (s_InsideWater)
|
||||
{
|
||||
return;
|
||||
}
|
||||
s_InsideWater = true;
|
||||
|
||||
// Actual water rendering mode depends on both the current setting AND
|
||||
// the hardware support. There's no point in rendering refraction textures
|
||||
// if they won't be visible in the end.
|
||||
m_HardwareWaterSupport = FindHardwareWaterSupport();
|
||||
WaterMode mode = GetWaterMode();
|
||||
|
||||
Camera reflectionCamera, refractionCamera;
|
||||
CreateWaterObjects(cam, out reflectionCamera, out refractionCamera);
|
||||
|
||||
// find out the reflection plane: position and normal in world space
|
||||
Vector3 pos = transform.position;
|
||||
Vector3 normal = transform.up;
|
||||
|
||||
// Optionally disable pixel lights for reflection/refraction
|
||||
int oldPixelLightCount = QualitySettings.pixelLightCount;
|
||||
if (disablePixelLights)
|
||||
{
|
||||
QualitySettings.pixelLightCount = 0;
|
||||
}
|
||||
|
||||
UpdateCameraModes(cam, reflectionCamera);
|
||||
UpdateCameraModes(cam, refractionCamera);
|
||||
|
||||
// Render reflection if needed
|
||||
if (mode >= WaterMode.Reflective)
|
||||
{
|
||||
// Reflect camera around reflection plane
|
||||
float d = -Vector3.Dot(normal, pos) - clipPlaneOffset;
|
||||
Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d);
|
||||
|
||||
Matrix4x4 reflection = Matrix4x4.zero;
|
||||
CalculateReflectionMatrix(ref reflection, reflectionPlane);
|
||||
Vector3 oldpos = cam.transform.position;
|
||||
Vector3 newpos = reflection.MultiplyPoint(oldpos);
|
||||
reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;
|
||||
|
||||
// Setup oblique projection matrix so that near plane is our reflection
|
||||
// plane. This way we clip everything below/above it for free.
|
||||
Vector4 clipPlane = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f);
|
||||
reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane);
|
||||
|
||||
reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer
|
||||
reflectionCamera.targetTexture = m_ReflectionTexture;
|
||||
GL.invertCulling = true;
|
||||
reflectionCamera.transform.position = newpos;
|
||||
Vector3 euler = cam.transform.eulerAngles;
|
||||
reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z);
|
||||
reflectionCamera.Render();
|
||||
reflectionCamera.transform.position = oldpos;
|
||||
GL.invertCulling = false;
|
||||
GetComponent<Renderer>().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture);
|
||||
}
|
||||
|
||||
// Render refraction
|
||||
if (mode >= WaterMode.Refractive)
|
||||
{
|
||||
refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix;
|
||||
|
||||
// Setup oblique projection matrix so that near plane is our reflection
|
||||
// plane. This way we clip everything below/above it for free.
|
||||
Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f);
|
||||
refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane);
|
||||
|
||||
refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; // never render water layer
|
||||
refractionCamera.targetTexture = m_RefractionTexture;
|
||||
refractionCamera.transform.position = cam.transform.position;
|
||||
refractionCamera.transform.rotation = cam.transform.rotation;
|
||||
refractionCamera.Render();
|
||||
GetComponent<Renderer>().sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture);
|
||||
}
|
||||
|
||||
// Restore pixel light count
|
||||
if (disablePixelLights)
|
||||
{
|
||||
QualitySettings.pixelLightCount = oldPixelLightCount;
|
||||
}
|
||||
|
||||
// Setup shader keywords based on water mode
|
||||
switch (mode)
|
||||
{
|
||||
case WaterMode.Simple:
|
||||
Shader.EnableKeyword("WATER_SIMPLE");
|
||||
Shader.DisableKeyword("WATER_REFLECTIVE");
|
||||
Shader.DisableKeyword("WATER_REFRACTIVE");
|
||||
break;
|
||||
case WaterMode.Reflective:
|
||||
Shader.DisableKeyword("WATER_SIMPLE");
|
||||
Shader.EnableKeyword("WATER_REFLECTIVE");
|
||||
Shader.DisableKeyword("WATER_REFRACTIVE");
|
||||
break;
|
||||
case WaterMode.Refractive:
|
||||
Shader.DisableKeyword("WATER_SIMPLE");
|
||||
Shader.DisableKeyword("WATER_REFLECTIVE");
|
||||
Shader.EnableKeyword("WATER_REFRACTIVE");
|
||||
break;
|
||||
}
|
||||
|
||||
s_InsideWater = false;
|
||||
}
|
||||
|
||||
|
||||
// Cleanup all the objects we possibly have created
|
||||
void OnDisable()
|
||||
{
|
||||
if (m_ReflectionTexture)
|
||||
{
|
||||
DestroyImmediate(m_ReflectionTexture);
|
||||
m_ReflectionTexture = null;
|
||||
}
|
||||
if (m_RefractionTexture)
|
||||
{
|
||||
DestroyImmediate(m_RefractionTexture);
|
||||
m_RefractionTexture = null;
|
||||
}
|
||||
foreach (var kvp in m_ReflectionCameras)
|
||||
{
|
||||
DestroyImmediate((kvp.Value).gameObject);
|
||||
}
|
||||
m_ReflectionCameras.Clear();
|
||||
foreach (var kvp in m_RefractionCameras)
|
||||
{
|
||||
DestroyImmediate((kvp.Value).gameObject);
|
||||
}
|
||||
m_RefractionCameras.Clear();
|
||||
}
|
||||
|
||||
|
||||
// This just sets up some matrices in the material; for really
|
||||
// old cards to make water texture scroll.
|
||||
void Update()
|
||||
{
|
||||
if (!GetComponent<Renderer>())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Material mat = GetComponent<Renderer>().sharedMaterial;
|
||||
if (!mat)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector4 waveSpeed = mat.GetVector("WaveSpeed");
|
||||
float waveScale = mat.GetFloat("_WaveScale");
|
||||
Vector4 waveScale4 = new Vector4(waveScale, waveScale, waveScale * 0.4f, waveScale * 0.45f);
|
||||
|
||||
// Time since level load, and do intermediate calculations with doubles
|
||||
double t = Time.timeSinceLevelLoad / 20.0;
|
||||
Vector4 offsetClamped = new Vector4(
|
||||
(float)Math.IEEERemainder(waveSpeed.x * waveScale4.x * t, 1.0),
|
||||
(float)Math.IEEERemainder(waveSpeed.y * waveScale4.y * t, 1.0),
|
||||
(float)Math.IEEERemainder(waveSpeed.z * waveScale4.z * t, 1.0),
|
||||
(float)Math.IEEERemainder(waveSpeed.w * waveScale4.w * t, 1.0)
|
||||
);
|
||||
|
||||
mat.SetVector("_WaveOffset", offsetClamped);
|
||||
mat.SetVector("_WaveScale4", waveScale4);
|
||||
}
|
||||
|
||||
void UpdateCameraModes(Camera src, Camera dest)
|
||||
{
|
||||
if (dest == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// set water camera to clear the same way as current camera
|
||||
dest.clearFlags = src.clearFlags;
|
||||
dest.backgroundColor = src.backgroundColor;
|
||||
if (src.clearFlags == CameraClearFlags.Skybox)
|
||||
{
|
||||
Skybox sky = src.GetComponent<Skybox>();
|
||||
Skybox mysky = dest.GetComponent<Skybox>();
|
||||
if (!sky || !sky.material)
|
||||
{
|
||||
mysky.enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mysky.enabled = true;
|
||||
mysky.material = sky.material;
|
||||
}
|
||||
}
|
||||
// update other values to match current camera.
|
||||
// even if we are supplying custom camera&projection matrices,
|
||||
// some of values are used elsewhere (e.g. skybox uses far plane)
|
||||
dest.farClipPlane = src.farClipPlane;
|
||||
dest.nearClipPlane = src.nearClipPlane;
|
||||
dest.orthographic = src.orthographic;
|
||||
dest.fieldOfView = src.fieldOfView;
|
||||
dest.aspect = src.aspect;
|
||||
dest.orthographicSize = src.orthographicSize;
|
||||
}
|
||||
|
||||
|
||||
// On-demand create any objects we need for water
|
||||
void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera)
|
||||
{
|
||||
WaterMode mode = GetWaterMode();
|
||||
|
||||
reflectionCamera = null;
|
||||
refractionCamera = null;
|
||||
|
||||
if (mode >= WaterMode.Reflective)
|
||||
{
|
||||
// Reflection render texture
|
||||
if (!m_ReflectionTexture || m_OldReflectionTextureSize != textureSize)
|
||||
{
|
||||
if (m_ReflectionTexture)
|
||||
{
|
||||
DestroyImmediate(m_ReflectionTexture);
|
||||
}
|
||||
m_ReflectionTexture = new RenderTexture(textureSize, textureSize, 16);
|
||||
m_ReflectionTexture.name = "__WaterReflection" + GetInstanceID();
|
||||
m_ReflectionTexture.isPowerOfTwo = true;
|
||||
m_ReflectionTexture.hideFlags = HideFlags.DontSave;
|
||||
m_OldReflectionTextureSize = textureSize;
|
||||
}
|
||||
|
||||
// Camera for reflection
|
||||
m_ReflectionCameras.TryGetValue(currentCamera, out reflectionCamera);
|
||||
if (!reflectionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO
|
||||
{
|
||||
GameObject go = new GameObject("Water Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox));
|
||||
reflectionCamera = go.GetComponent<Camera>();
|
||||
reflectionCamera.enabled = false;
|
||||
reflectionCamera.transform.position = transform.position;
|
||||
reflectionCamera.transform.rotation = transform.rotation;
|
||||
reflectionCamera.gameObject.AddComponent<FlareLayer>();
|
||||
go.hideFlags = HideFlags.HideAndDontSave;
|
||||
m_ReflectionCameras[currentCamera] = reflectionCamera;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode >= WaterMode.Refractive)
|
||||
{
|
||||
// Refraction render texture
|
||||
if (!m_RefractionTexture || m_OldRefractionTextureSize != textureSize)
|
||||
{
|
||||
if (m_RefractionTexture)
|
||||
{
|
||||
DestroyImmediate(m_RefractionTexture);
|
||||
}
|
||||
m_RefractionTexture = new RenderTexture(textureSize, textureSize, 16);
|
||||
m_RefractionTexture.name = "__WaterRefraction" + GetInstanceID();
|
||||
m_RefractionTexture.isPowerOfTwo = true;
|
||||
m_RefractionTexture.hideFlags = HideFlags.DontSave;
|
||||
m_OldRefractionTextureSize = textureSize;
|
||||
}
|
||||
|
||||
// Camera for refraction
|
||||
m_RefractionCameras.TryGetValue(currentCamera, out refractionCamera);
|
||||
if (!refractionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO
|
||||
{
|
||||
GameObject go =
|
||||
new GameObject("Water Refr Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(),
|
||||
typeof(Camera), typeof(Skybox));
|
||||
refractionCamera = go.GetComponent<Camera>();
|
||||
refractionCamera.enabled = false;
|
||||
refractionCamera.transform.position = transform.position;
|
||||
refractionCamera.transform.rotation = transform.rotation;
|
||||
refractionCamera.gameObject.AddComponent<FlareLayer>();
|
||||
go.hideFlags = HideFlags.HideAndDontSave;
|
||||
m_RefractionCameras[currentCamera] = refractionCamera;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WaterMode GetWaterMode()
|
||||
{
|
||||
if (m_HardwareWaterSupport < waterMode)
|
||||
{
|
||||
return m_HardwareWaterSupport;
|
||||
}
|
||||
return waterMode;
|
||||
}
|
||||
|
||||
WaterMode FindHardwareWaterSupport()
|
||||
{
|
||||
if (!GetComponent<Renderer>())
|
||||
{
|
||||
return WaterMode.Simple;
|
||||
}
|
||||
|
||||
Material mat = GetComponent<Renderer>().sharedMaterial;
|
||||
if (!mat)
|
||||
{
|
||||
return WaterMode.Simple;
|
||||
}
|
||||
|
||||
string mode = mat.GetTag("WATERMODE", false);
|
||||
if (mode == "Refractive")
|
||||
{
|
||||
return WaterMode.Refractive;
|
||||
}
|
||||
if (mode == "Reflective")
|
||||
{
|
||||
return WaterMode.Reflective;
|
||||
}
|
||||
|
||||
return WaterMode.Simple;
|
||||
}
|
||||
|
||||
// Given position/normal of the plane, calculates plane in camera space.
|
||||
Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign)
|
||||
{
|
||||
Vector3 offsetPos = pos + normal * clipPlaneOffset;
|
||||
Matrix4x4 m = cam.worldToCameraMatrix;
|
||||
Vector3 cpos = m.MultiplyPoint(offsetPos);
|
||||
Vector3 cnormal = m.MultiplyVector(normal).normalized * sideSign;
|
||||
return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal));
|
||||
}
|
||||
|
||||
// Calculates reflection matrix around the given plane
|
||||
static void CalculateReflectionMatrix(ref Matrix4x4 reflectionMat, Vector4 plane)
|
||||
{
|
||||
reflectionMat.m00 = (1F - 2F * plane[0] * plane[0]);
|
||||
reflectionMat.m01 = (- 2F * plane[0] * plane[1]);
|
||||
reflectionMat.m02 = (- 2F * plane[0] * plane[2]);
|
||||
reflectionMat.m03 = (- 2F * plane[3] * plane[0]);
|
||||
|
||||
reflectionMat.m10 = (- 2F * plane[1] * plane[0]);
|
||||
reflectionMat.m11 = (1F - 2F * plane[1] * plane[1]);
|
||||
reflectionMat.m12 = (- 2F * plane[1] * plane[2]);
|
||||
reflectionMat.m13 = (- 2F * plane[3] * plane[1]);
|
||||
|
||||
reflectionMat.m20 = (- 2F * plane[2] * plane[0]);
|
||||
reflectionMat.m21 = (- 2F * plane[2] * plane[1]);
|
||||
reflectionMat.m22 = (1F - 2F * plane[2] * plane[2]);
|
||||
reflectionMat.m23 = (- 2F * plane[3] * plane[2]);
|
||||
|
||||
reflectionMat.m30 = 0F;
|
||||
reflectionMat.m31 = 0F;
|
||||
reflectionMat.m32 = 0F;
|
||||
reflectionMat.m33 = 1F;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3d3ef1a5bbfb4e0a910fbbe5830b1f9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.Water
|
||||
{
|
||||
public enum WaterQuality
|
||||
{
|
||||
High = 2,
|
||||
Medium = 1,
|
||||
Low = 0,
|
||||
}
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public class WaterBase : MonoBehaviour
|
||||
{
|
||||
public Material sharedMaterial;
|
||||
public WaterQuality waterQuality = WaterQuality.High;
|
||||
public bool edgeBlend = true;
|
||||
|
||||
|
||||
public void UpdateShader()
|
||||
{
|
||||
if (waterQuality > WaterQuality.Medium)
|
||||
{
|
||||
sharedMaterial.shader.maximumLOD = 501;
|
||||
}
|
||||
else if (waterQuality > WaterQuality.Low)
|
||||
{
|
||||
sharedMaterial.shader.maximumLOD = 301;
|
||||
}
|
||||
else
|
||||
{
|
||||
sharedMaterial.shader.maximumLOD = 201;
|
||||
}
|
||||
|
||||
// If the system does not support depth textures (ie. NaCl), turn off edge bleeding,
|
||||
// as the shader will render everything as transparent if the depth texture is not valid.
|
||||
if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.Depth))
|
||||
{
|
||||
edgeBlend = false;
|
||||
}
|
||||
|
||||
if (edgeBlend)
|
||||
{
|
||||
Shader.EnableKeyword("WATER_EDGEBLEND_ON");
|
||||
Shader.DisableKeyword("WATER_EDGEBLEND_OFF");
|
||||
// just to make sure (some peeps might forget to add a water tile to the patches)
|
||||
if (Camera.main)
|
||||
{
|
||||
Camera.main.depthTextureMode |= DepthTextureMode.Depth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Shader.EnableKeyword("WATER_EDGEBLEND_OFF");
|
||||
Shader.DisableKeyword("WATER_EDGEBLEND_ON");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void WaterTileBeingRendered(Transform tr, Camera currentCam)
|
||||
{
|
||||
if (currentCam && edgeBlend)
|
||||
{
|
||||
currentCam.depthTextureMode |= DepthTextureMode.Depth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (sharedMaterial)
|
||||
{
|
||||
UpdateShader();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1da353243062479a9b31c85074a796b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityStandardAssets.Water
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
public class WaterTile : MonoBehaviour
|
||||
{
|
||||
public PlanarReflection reflection;
|
||||
public WaterBase waterBase;
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
AcquireComponents();
|
||||
}
|
||||
|
||||
|
||||
void AcquireComponents()
|
||||
{
|
||||
if (!reflection)
|
||||
{
|
||||
if (transform.parent)
|
||||
{
|
||||
reflection = transform.parent.GetComponent<PlanarReflection>();
|
||||
}
|
||||
else
|
||||
{
|
||||
reflection = transform.GetComponent<PlanarReflection>();
|
||||
}
|
||||
}
|
||||
|
||||
if (!waterBase)
|
||||
{
|
||||
if (transform.parent)
|
||||
{
|
||||
waterBase = transform.parent.GetComponent<WaterBase>();
|
||||
}
|
||||
else
|
||||
{
|
||||
waterBase = transform.GetComponent<WaterBase>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public void Update()
|
||||
{
|
||||
AcquireComponents();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public void OnWillRenderObject()
|
||||
{
|
||||
if (reflection)
|
||||
{
|
||||
reflection.WaterTileBeingRendered(transform, Camera.current);
|
||||
}
|
||||
if (waterBase)
|
||||
{
|
||||
waterBase.WaterTileBeingRendered(transform, Camera.current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a91e8dd37cdd41efb4859b65aced7a2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17fa625ce6e43384aa2e96586473ccb6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
301
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODPreview.cs
vendored
Normal file
301
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODPreview.cs
vendored
Normal file
@@ -0,0 +1,301 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Threading;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UltimateGameTools.MeshSimplifier;
|
||||
|
||||
public class LODPreview : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public class ShowcaseObject
|
||||
{
|
||||
public AutomaticLOD m_automaticLOD;
|
||||
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.W))
|
||||
{
|
||||
m_bWireframe = !m_bWireframe;
|
||||
SetWireframe(m_bWireframe);
|
||||
}
|
||||
|
||||
if (m_selectedAutomaticLOD != null)
|
||||
{
|
||||
if (Input.GetMouseButton(0) && Input.mousePosition.y > 100)
|
||||
{
|
||||
Vector3 v3Angles = ShowcaseObjects[m_nSelectedIndex].m_rotationAxis * -((Input.mousePosition.x - m_fLastMouseX) * MouseSensitvity);
|
||||
m_selectedAutomaticLOD.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_selectedAutomaticLOD.transform.Rotate(v3Angles, Space.Self);
|
||||
}
|
||||
}
|
||||
|
||||
m_fLastMouseX = Input.mousePosition.x;
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
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, 430), "");
|
||||
|
||||
GUILayout.Label("Select model:", GUILayout.Width(nWidth));
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
for (int i = 0; i < ShowcaseObjects.Length; i++)
|
||||
{
|
||||
if (GUILayout.Button(ShowcaseObjects[i].m_automaticLOD.name) && bAllowInteract)
|
||||
{
|
||||
if (m_selectedAutomaticLOD != null)
|
||||
{
|
||||
DestroyImmediate(m_selectedAutomaticLOD.gameObject);
|
||||
}
|
||||
|
||||
SetActiveObject(i);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (m_selectedAutomaticLOD != 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_selectedAutomaticLOD != null)
|
||||
{
|
||||
SetWireframe(m_bWireframe);
|
||||
}
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
GUILayout.Label("Select predefined LOD:");
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
for (int i = 0; i < m_selectedAutomaticLOD.GetLODLevelCount(); i++)
|
||||
{
|
||||
if (GUILayout.Button("LOD " + i) && bAllowInteract)
|
||||
{
|
||||
m_selectedAutomaticLOD.SwitchToLOD(i, true);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
GUILayout.Label("Vertex count: " + m_selectedAutomaticLOD.GetCurrentVertexCount(true) + "/" + m_selectedAutomaticLOD.GetOriginalVertexCount(true));
|
||||
|
||||
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 custom LOD", GUILayout.Width(200)))
|
||||
{
|
||||
StartCoroutine(ComputeLODWithVertices(m_fVertexAmount));
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetActiveObject(int index)
|
||||
{
|
||||
m_nSelectedIndex = index;
|
||||
|
||||
AutomaticLOD automaticLOD = Instantiate(ShowcaseObjects[index].m_automaticLOD);
|
||||
automaticLOD.transform.position = ShowcaseObjects[index].m_position;
|
||||
automaticLOD.transform.rotation = Quaternion.Euler(ShowcaseObjects[index].m_angles);
|
||||
|
||||
m_selectedAutomaticLOD = automaticLOD;
|
||||
automaticLOD.SetAutomaticCameraLODSwitch(false);
|
||||
|
||||
m_objectMaterials = new Dictionary<GameObject, Material[]>();
|
||||
AddMaterials(automaticLOD.gameObject, m_objectMaterials);
|
||||
|
||||
m_bWireframe = false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 ComputeLODWithVertices(float fAmount)
|
||||
{
|
||||
foreach (KeyValuePair<GameObject, Material[]> pair in m_objectMaterials)
|
||||
{
|
||||
AutomaticLOD automaticLOD = pair.Key.GetComponent<AutomaticLOD>();
|
||||
MeshFilter meshFilter = pair.Key.GetComponent<MeshFilter>();
|
||||
SkinnedMeshRenderer skin = pair.Key.GetComponent<SkinnedMeshRenderer>();
|
||||
|
||||
if (automaticLOD && (meshFilter != null || skin != null))
|
||||
{
|
||||
Mesh newMesh = null;
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
newMesh = Mesh.Instantiate(meshFilter.sharedMesh);
|
||||
}
|
||||
else if (skin != null)
|
||||
{
|
||||
newMesh = Mesh.Instantiate(skin.sharedMesh);
|
||||
}
|
||||
|
||||
automaticLOD.GetMeshSimplifier().CoroutineEnded = false;
|
||||
|
||||
StartCoroutine(automaticLOD.GetMeshSimplifier().ComputeMeshWithVertexCount(pair.Key, newMesh, Mathf.RoundToInt(fAmount * automaticLOD.GetMeshSimplifier().GetOriginalMeshUniqueVertexCount()), automaticLOD.name, Progress));
|
||||
|
||||
while (automaticLOD.GetMeshSimplifier().CoroutineEnded == false)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (meshFilter != null)
|
||||
{
|
||||
meshFilter.mesh = newMesh;
|
||||
}
|
||||
else if (skin != null)
|
||||
{
|
||||
skin.sharedMesh = newMesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_strLastTitle = "";
|
||||
m_strLastMessage = "";
|
||||
m_nLastProgress = 0;
|
||||
}
|
||||
|
||||
Dictionary<GameObject, Material[]> m_objectMaterials;
|
||||
AutomaticLOD m_selectedAutomaticLOD;
|
||||
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;
|
||||
|
||||
}
|
||||
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODPreview.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODPreview.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a8108f029c393b4e9408d6d07364ab9
|
||||
timeCreated: 1434752013
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
258
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODSampleLODScene.cs
vendored
Normal file
258
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODSampleLODScene.cs
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
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
|
||||
}
|
||||
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODSampleLODScene.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODSampleLODScene.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5811c134011b7ac469bb48c134040d30
|
||||
timeCreated: 1438106980
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
48
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODSceneSelection.cs
vendored
Normal file
48
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODSceneSelection.cs
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class LODSceneSelection : MonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
public class SceneOption
|
||||
{
|
||||
public string m_sceneName;
|
||||
public string m_sceneDisplayName;
|
||||
}
|
||||
|
||||
public int BoxWidth = 300;
|
||||
public int BoxHeight = 50;
|
||||
public int MarginH = 20;
|
||||
public int MarginV = 20;
|
||||
|
||||
public SceneOption[] SceneOptions;
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
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);
|
||||
|
||||
GUILayout.Label("Scene selection:");
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
foreach(SceneOption sceneOption in SceneOptions)
|
||||
{
|
||||
if(GUILayout.Button(sceneOption.m_sceneDisplayName))
|
||||
{
|
||||
UnityEngine.SceneManagement.SceneManager.LoadScene(sceneOption.m_sceneName);
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Exit"))
|
||||
{
|
||||
Application.Quit();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODSceneSelection.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Data/Scripts/LODSceneSelection.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5cf189c258aa10a4eb03811a139fdea0
|
||||
timeCreated: 1438135577
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Editor.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Editor.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0889086c0bdcc3459025a94be2da0b4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1894
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Editor/AutomaticLODEditor.cs
vendored
Normal file
1894
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Editor/AutomaticLODEditor.cs
vendored
Normal file
File diff suppressed because one or more lines are too long
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Editor/AutomaticLODEditor.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Editor/AutomaticLODEditor.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d15024d8291bfb3408ecafe326e6f235
|
||||
timeCreated: 1434653206
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Scripts.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Scripts.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2cb20282246102f4db576c4bfaae571e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
2179
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Scripts/AutomaticLOD.cs
vendored
Normal file
2179
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Scripts/AutomaticLOD.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Scripts/AutomaticLOD.cs.meta
vendored
Normal file
12
Assets/ThirdParty/Tools/Ultimate Game Tools/AutomaticLOD/Scripts/AutomaticLOD.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e90785789c206fa4e951b02cff2c61c8
|
||||
timeCreated: 1434653219
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify.meta
vendored
Normal file
8
Assets/ThirdParty/Tools/Ultimate Game Tools/MeshSimplify.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 157cba43bc196cc44b6231165942c1f6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
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