382 lines
12 KiB
C#
382 lines
12 KiB
C#
|
/**
|
||
|
* \brief Hax! DLLs cannot interpret preprocessor directives, so this class acts as a "bridge"
|
||
|
*/
|
||
|
using System;
|
||
|
using UnityEngine;
|
||
|
using System.Collections;
|
||
|
|
||
|
namespace DigitalOpus.MB.Core
|
||
|
{
|
||
|
|
||
|
public class MBVersionConcrete : MBVersionInterface
|
||
|
{
|
||
|
public string version()
|
||
|
{
|
||
|
return "3.28.1";
|
||
|
}
|
||
|
|
||
|
public int GetMajorVersion()
|
||
|
{
|
||
|
/*
|
||
|
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
|
||
|
return 3;
|
||
|
#elif UNITY_4_0 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7
|
||
|
return 4;
|
||
|
#else
|
||
|
return 5;
|
||
|
#endif
|
||
|
*/
|
||
|
string v = Application.unityVersion;
|
||
|
String[] vs = v.Split(new char[] { '.' });
|
||
|
return Int32.Parse(vs[0]);
|
||
|
}
|
||
|
|
||
|
public int GetMinorVersion()
|
||
|
{
|
||
|
/*
|
||
|
#if UNITY_3_0 || UNITY_3_0_0
|
||
|
return 0;
|
||
|
#elif UNITY_3_1
|
||
|
return 1;
|
||
|
#elif UNITY_3_2
|
||
|
return 2;
|
||
|
#elif UNITY_3_3
|
||
|
return 3;
|
||
|
#elif UNITY_3_4
|
||
|
return 4;
|
||
|
#elif UNITY_3_5
|
||
|
return 5;
|
||
|
#elif UNITY_4_0 || UNITY_4_0_1
|
||
|
return 0;
|
||
|
#elif UNITY_4_1
|
||
|
return 1;
|
||
|
#elif UNITY_4_2
|
||
|
return 2;
|
||
|
#elif UNITY_4_3
|
||
|
return 3;
|
||
|
#elif UNITY_4_4
|
||
|
return 4;
|
||
|
#elif UNITY_4_5
|
||
|
return 5;
|
||
|
#else
|
||
|
return 0;
|
||
|
#endif
|
||
|
*/
|
||
|
string v = Application.unityVersion;
|
||
|
String[] vs = v.Split(new char[] { '.' });
|
||
|
return Int32.Parse(vs[1]);
|
||
|
}
|
||
|
|
||
|
public bool GetActive(GameObject go)
|
||
|
{
|
||
|
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
|
||
|
return go.active;
|
||
|
#else
|
||
|
return go.activeInHierarchy;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public void SetActive(GameObject go, bool isActive)
|
||
|
{
|
||
|
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
|
||
|
go.active = isActive;
|
||
|
#else
|
||
|
go.SetActive(isActive);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public void SetActiveRecursively(GameObject go, bool isActive)
|
||
|
{
|
||
|
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
|
||
|
go.SetActiveRecursively(isActive);
|
||
|
#else
|
||
|
go.SetActive(isActive);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public UnityEngine.Object[] FindSceneObjectsOfType(Type t)
|
||
|
{
|
||
|
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
|
||
|
return GameObject.FindSceneObjectsOfType(t);
|
||
|
#else
|
||
|
return GameObject.FindObjectsOfType(t);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public void OptimizeMesh(Mesh m)
|
||
|
{
|
||
|
#if UNITY_EDITOR
|
||
|
#if UNITY_5_5_OR_NEWER
|
||
|
UnityEditor.MeshUtility.Optimize(m);
|
||
|
#else
|
||
|
m.Optimize();
|
||
|
#endif
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
public bool IsRunningAndMeshNotReadWriteable(Mesh m)
|
||
|
{
|
||
|
if (Application.isPlaying)
|
||
|
{
|
||
|
#if UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5
|
||
|
return false;
|
||
|
#else
|
||
|
return !m.isReadable;
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Vector2 _HALF_UV = new Vector2(.5f, .5f);
|
||
|
public Vector2[] GetMeshUV1s(Mesh m, MB2_LogLevel LOG_LEVEL)
|
||
|
{
|
||
|
Vector2[] uv;
|
||
|
#if (UNITY_4_6 || UNITY_4_7 || UNITY_4_5 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5)
|
||
|
uv = m.uv1;
|
||
|
|
||
|
#else
|
||
|
if (LOG_LEVEL >= MB2_LogLevel.warn) MB2_Log.LogDebug("UV1 does not exist in Unity 5+");
|
||
|
uv = m.uv;
|
||
|
#endif
|
||
|
if (uv.Length == 0)
|
||
|
{
|
||
|
if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Mesh " + m + " has no uv1s. Generating");
|
||
|
if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Mesh " + m + " didn't have uv1s. Generating uv1s.");
|
||
|
uv = new Vector2[m.vertexCount];
|
||
|
for (int i = 0; i < uv.Length; i++) { uv[i] = _HALF_UV; }
|
||
|
}
|
||
|
return uv;
|
||
|
}
|
||
|
|
||
|
public Vector2[] GetMeshUV3orUV4(Mesh m, bool get3, MB2_LogLevel LOG_LEVEL)
|
||
|
{
|
||
|
Vector2[] uvs;
|
||
|
#if (UNITY_4_6 || UNITY_4_7 || UNITY_4_5 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5)
|
||
|
if (LOG_LEVEL >= MB2_LogLevel.warn) MB2_Log.LogDebug("UV3 and UV4 do not exist in Unity 4");
|
||
|
uvs = m.uv;
|
||
|
#else
|
||
|
if (get3) uvs = m.uv3;
|
||
|
else uvs = m.uv4;
|
||
|
#endif
|
||
|
if (uvs.Length == 0)
|
||
|
{
|
||
|
if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Mesh " + m + " has no uv" + (get3 ? "3" : "4") + ". Generating");
|
||
|
uvs = new Vector2[m.vertexCount];
|
||
|
for (int i = 0; i < uvs.Length; i++) { uvs[i] = _HALF_UV; }
|
||
|
}
|
||
|
return uvs;
|
||
|
}
|
||
|
|
||
|
public void MeshClear(Mesh m, bool t)
|
||
|
{
|
||
|
#if UNITY_3_5
|
||
|
m.Clear();
|
||
|
#else
|
||
|
m.Clear(t);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public void MeshAssignUV3(Mesh m, Vector2[] uv3s)
|
||
|
{
|
||
|
#if (UNITY_4_6 || UNITY_4_7 || UNITY_4_5 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5)
|
||
|
Debug.LogWarning("UV3 was checked but UV3 does not exist in Unity 4");
|
||
|
#else
|
||
|
m.uv3 = uv3s;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public void MeshAssignUV4(Mesh m, Vector2[] uv4s)
|
||
|
{
|
||
|
#if (UNITY_4_6 || UNITY_4_7 || UNITY_4_5 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5)
|
||
|
Debug.LogWarning("UV4 was checked but UV4 does not exist in Unity 4");
|
||
|
#else
|
||
|
m.uv4 = uv4s;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public Vector4 GetLightmapTilingOffset(Renderer r)
|
||
|
{
|
||
|
#if (UNITY_4_6 || UNITY_4_7 || UNITY_4_5 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5)
|
||
|
return r.lightmapTilingOffset ;
|
||
|
#else
|
||
|
return r.lightmapScaleOffset; //r.lightmapScaleOffset ;
|
||
|
#endif
|
||
|
}
|
||
|
#if UNITY_5_OR_NEWER
|
||
|
public Transform[] GetBones(Renderer r)
|
||
|
{
|
||
|
if (r is SkinnedMeshRenderer)
|
||
|
{
|
||
|
Transform[] bone;
|
||
|
//check if I need to deoptimize
|
||
|
Animator anim = r.GetComponentInParent<Animator>();
|
||
|
|
||
|
if (anim != null)
|
||
|
{
|
||
|
if (anim.hasTransformHierarchy)
|
||
|
{
|
||
|
//nothing to do
|
||
|
} else if (anim.isOptimizable)
|
||
|
{
|
||
|
//Deoptimize
|
||
|
AnimatorUtility.DeoptimizeTransformHierarchy(anim.gameObject);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Debug.LogError("Could not getBones. Bones optimized but could not create TransformHierarchy.");
|
||
|
return null;
|
||
|
}
|
||
|
bone = ((SkinnedMeshRenderer)r).bones;
|
||
|
//can't deoptimize here because the transforms need to exist for the combined mesh
|
||
|
} else
|
||
|
{
|
||
|
//no Animator component but check to see if bones were optimized on import
|
||
|
bone = ((SkinnedMeshRenderer)r).bones;
|
||
|
#if UNITY_EDITOR
|
||
|
if (bone.Length == 0)
|
||
|
{
|
||
|
Mesh m = ((SkinnedMeshRenderer)r).sharedMesh;
|
||
|
if (m.bindposes.Length != bone.Length) Debug.LogError("SkinnedMesh (" + r.gameObject + ") in the list of objects to combine has no bones. Check that 'optimize game object' is not checked in the 'Rig' tab of the asset importer. Mesh Baker cannot combine optimized skinned meshes because the bones are not available.");
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
return bone;
|
||
|
}
|
||
|
else if (r is MeshRenderer)
|
||
|
{
|
||
|
Transform[] bone = new Transform[1];
|
||
|
bone[0] = r.transform;
|
||
|
return bone;
|
||
|
}
|
||
|
else {
|
||
|
Debug.LogError("Could not getBones. Object is not a Renderer.");
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
#else
|
||
|
public Transform[] GetBones(Renderer r)
|
||
|
{
|
||
|
if (r is SkinnedMeshRenderer)
|
||
|
{
|
||
|
Transform[] bone = ((SkinnedMeshRenderer)r).bones;
|
||
|
#if UNITY_EDITOR
|
||
|
if (bone.Length == 0)
|
||
|
{
|
||
|
Mesh m = ((SkinnedMeshRenderer)r).sharedMesh;
|
||
|
if (m.bindposes.Length != bone.Length) Debug.LogError("SkinnedMesh (" + r.gameObject + ") in the list of objects to combine has no bones. Check that 'optimize game object' is not checked in the 'Rig' tab of the asset importer. Mesh Baker cannot combine optimized skinned meshes because the bones are not available.");
|
||
|
}
|
||
|
#endif
|
||
|
return bone;
|
||
|
}
|
||
|
else if (r is MeshRenderer)
|
||
|
{
|
||
|
Transform[] bone = new Transform[1];
|
||
|
bone[0] = r.transform;
|
||
|
return bone;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Debug.LogError("Could not getBones. Object does not have a renderer");
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
public int GetBlendShapeFrameCount(Mesh m, int shapeIndex)
|
||
|
{
|
||
|
#if UNITY_5_3_OR_NEWER
|
||
|
return m.GetBlendShapeFrameCount(shapeIndex);
|
||
|
#else
|
||
|
return 0;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public float GetBlendShapeFrameWeight(Mesh m, int shapeIndex, int frameIndex)
|
||
|
{
|
||
|
#if UNITY_5_3_OR_NEWER
|
||
|
return m.GetBlendShapeFrameWeight(shapeIndex, frameIndex);
|
||
|
#else
|
||
|
return 0;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public void GetBlendShapeFrameVertices(Mesh m, int shapeIndex, int frameIndex, Vector3[] vs, Vector3[] ns, Vector3[] ts)
|
||
|
{
|
||
|
#if UNITY_5_3_OR_NEWER
|
||
|
m.GetBlendShapeFrameVertices(shapeIndex, frameIndex, vs, ns, ts);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public void ClearBlendShapes(Mesh m)
|
||
|
{
|
||
|
#if UNITY_5_3_OR_NEWER
|
||
|
m.ClearBlendShapes();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public void AddBlendShapeFrame(Mesh m, string nm, float wt, Vector3[] vs, Vector3[] ns, Vector3[] ts)
|
||
|
{
|
||
|
#if UNITY_5_3_OR_NEWER
|
||
|
m.AddBlendShapeFrame(nm, wt, vs, ns, ts);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public int MaxMeshVertexCount()
|
||
|
{
|
||
|
#if UNITY_2017_3_OR_NEWER
|
||
|
return 2147483646;
|
||
|
#else
|
||
|
return 65535;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
public void SetMeshIndexFormatAndClearMesh(Mesh m, int numVerts, bool vertices, bool justClearTriangles)
|
||
|
{
|
||
|
#if UNITY_2017_3_OR_NEWER
|
||
|
if (vertices && numVerts > 65534 && m.indexFormat == UnityEngine.Rendering.IndexFormat.UInt16)
|
||
|
{
|
||
|
MBVersion.MeshClear(m, false);
|
||
|
m.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
|
||
|
return;
|
||
|
}
|
||
|
else if (vertices && numVerts <= 65534 && m.indexFormat == UnityEngine.Rendering.IndexFormat.UInt32)
|
||
|
{
|
||
|
MBVersion.MeshClear(m, false);
|
||
|
m.indexFormat = UnityEngine.Rendering.IndexFormat.UInt16;
|
||
|
return;
|
||
|
}
|
||
|
#endif
|
||
|
if (justClearTriangles)
|
||
|
{
|
||
|
MBVersion.MeshClear(m, true); //clear just triangles
|
||
|
}
|
||
|
else
|
||
|
{//clear all the data and start with a blank mesh
|
||
|
MBVersion.MeshClear(m, false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool GraphicsUVStartsAtTop()
|
||
|
{
|
||
|
#if UNITY_2017_1_OR_NEWER
|
||
|
return SystemInfo.graphicsUVStartsAtTop;
|
||
|
#else
|
||
|
if (SystemInfo.graphicsDeviceVersion.Contains("metal"))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// "opengl es, direct3d"
|
||
|
return true;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|