123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- //----------------------------------------------
- // MeshBaker
- // Copyright © 2011-2012 Ian Deane
- //----------------------------------------------
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System;
- namespace DigitalOpus.MB.Core{
- public class MB_Utility{
- public static bool DO_INTEGRITY_CHECKS = false;
- public struct MeshAnalysisResult{
- public Rect uvRect;
- public bool hasOutOfBoundsUVs;
- public bool hasOverlappingSubmeshVerts;
- public bool hasOverlappingSubmeshTris;
- public bool hasUVs;
- public float submeshArea;
- }
- public static Texture2D createTextureCopy(Texture2D source){
- Texture2D newTex = new Texture2D(source.width,source.height,TextureFormat.ARGB32,true);
- newTex.SetPixels(source.GetPixels());
- return newTex;
- }
-
- public static bool ArrayBIsSubsetOfA(System.Object[] a, System.Object[] b){
- for (int i = 0; i < b.Length; i++){
- bool foundBinA = false;
- for (int j = 0; j < a.Length; j++){
- if (a[j] == b[i]){
- foundBinA = true;
- break;
- }
- }
- if (foundBinA == false) return false;
- }
- return true;
- }
- public static Material[] GetGOMaterials(GameObject go){
- if (go == null) return new Material[0];
- Material[] sharedMaterials = null;
- Mesh mesh = null;
- MeshRenderer mr = go.GetComponent<MeshRenderer>();
- if (mr != null){
- sharedMaterials = mr.sharedMaterials;
- MeshFilter mf = go.GetComponent<MeshFilter>();
- if (mf == null){
- throw new Exception("Object " + go + " has a MeshRenderer but no MeshFilter.");
- }
- mesh = mf.sharedMesh;
- }
-
- SkinnedMeshRenderer smr = go.GetComponent<SkinnedMeshRenderer>();
- if (smr != null){
- sharedMaterials = smr.sharedMaterials;
- mesh = smr.sharedMesh;
- }
-
- if (sharedMaterials == null){
- Debug.LogError("Object " + go.name + " does not have a MeshRenderer or a SkinnedMeshRenderer component");
- return new Material[0];
- } else if (mesh == null){
- Debug.LogError("Object " + go.name + " has a MeshRenderer or SkinnedMeshRenderer but no mesh.");
- return new Material[0];
- } else {
- if (mesh.subMeshCount < sharedMaterials.Length){
- Debug.LogWarning("Object " + go + " has only " + mesh.subMeshCount + " submeshes and has " + sharedMaterials.Length + " materials. Extra materials do nothing.");
- Material[] newSharedMaterials = new Material[mesh.subMeshCount];
- Array.Copy(sharedMaterials,newSharedMaterials,newSharedMaterials.Length);
- sharedMaterials = newSharedMaterials;
- }
- return sharedMaterials;
- }
- }
-
- public static Mesh GetMesh(GameObject go){
- if (go == null) return null;
- MeshFilter mf = go.GetComponent<MeshFilter>();
- if (mf != null){
- return mf.sharedMesh;
- }
-
- SkinnedMeshRenderer smr = go.GetComponent<SkinnedMeshRenderer>();
- if (smr != null){
- return smr.sharedMesh;
- }
-
- return null;
- }
-
- public static void SetMesh(GameObject go, Mesh m)
- {
- if (go == null) return;
- MeshFilter mf = go.GetComponent<MeshFilter>();
- if (mf != null)
- {
- mf.sharedMesh = m;
- }
- else
- {
- SkinnedMeshRenderer smr = go.GetComponent<SkinnedMeshRenderer>();
- if (smr != null)
- {
- smr.sharedMesh = m;
- }
- }
- }
- public static Renderer GetRenderer(GameObject go){
- if (go == null) return null;
- MeshRenderer mr = go.GetComponent<MeshRenderer>();
- if (mr != null) return mr;
-
-
- SkinnedMeshRenderer smr = go.GetComponent<SkinnedMeshRenderer>();
- if (smr != null) return smr;
- return null;
- }
-
- public static void DisableRendererInSource(GameObject go){
- if (go == null) return;
- MeshRenderer mf = go.GetComponent<MeshRenderer>();
- if (mf != null){
- mf.enabled = false;
- return;
- }
-
- SkinnedMeshRenderer smr = go.GetComponent<SkinnedMeshRenderer>();
- if (smr != null){
- smr.enabled = false;
- return;
- }
- }
-
- public static bool hasOutOfBoundsUVs(Mesh m, ref Rect uvBounds){
- MeshAnalysisResult mar = new MeshAnalysisResult();
- bool outVal = hasOutOfBoundsUVs(m, ref mar);
- uvBounds = mar.uvRect;
- return outVal;
- }
- public static bool hasOutOfBoundsUVs(Mesh m, ref MeshAnalysisResult putResultHere, int submeshIndex = -1, int uvChannel = 0)
- {
- if (m == null)
- {
- putResultHere.hasOutOfBoundsUVs = false;
- return putResultHere.hasOutOfBoundsUVs;
- }
- Vector2[] uvs;
- if (uvChannel == 0) {
- uvs = m.uv;
- } else if (uvChannel == 1)
- {
- uvs = m.uv2;
- } else if (uvChannel == 2)
- {
- uvs = m.uv3;
- } else {
- uvs = m.uv4;
- }
- return hasOutOfBoundsUVs(uvs, m, ref putResultHere, submeshIndex);
- }
- public static bool hasOutOfBoundsUVs(Vector2[] uvs, Mesh m, ref MeshAnalysisResult putResultHere, int submeshIndex = -1)
- {
- putResultHere.hasUVs = true;
- if (uvs.Length == 0)
- {
- putResultHere.hasUVs = false;
- putResultHere.hasOutOfBoundsUVs = false;
- putResultHere.uvRect = new Rect();
- return putResultHere.hasOutOfBoundsUVs;
- }
- float minx, miny, maxx, maxy;
- if (submeshIndex >= m.subMeshCount)
- {
- putResultHere.hasOutOfBoundsUVs = false;
- putResultHere.uvRect = new Rect();
- return putResultHere.hasOutOfBoundsUVs;
- }
- else if (submeshIndex >= 0)
- {
- //checking specific submesh
- int[] tris = m.GetTriangles(submeshIndex);
- if (tris.Length == 0)
- {
- putResultHere.hasOutOfBoundsUVs = false;
- putResultHere.uvRect = new Rect();
- return putResultHere.hasOutOfBoundsUVs;
- }
- minx = maxx = uvs[tris[0]].x;
- miny = maxy = uvs[tris[0]].y;
- for (int idx = 0; idx < tris.Length; idx++)
- {
- int i = tris[idx];
- if (uvs[i].x < minx) minx = uvs[i].x;
- if (uvs[i].x > maxx) maxx = uvs[i].x;
- if (uvs[i].y < miny) miny = uvs[i].y;
- if (uvs[i].y > maxy) maxy = uvs[i].y;
- }
- }
- else {
- //checking all UVs
- minx = maxx = uvs[0].x;
- miny = maxy = uvs[0].y;
- for (int i = 0; i < uvs.Length; i++)
- {
- if (uvs[i].x < minx) minx = uvs[i].x;
- if (uvs[i].x > maxx) maxx = uvs[i].x;
- if (uvs[i].y < miny) miny = uvs[i].y;
- if (uvs[i].y > maxy) maxy = uvs[i].y;
- }
- }
- Rect uvBounds = new Rect();
- uvBounds.x = minx;
- uvBounds.y = miny;
- uvBounds.width = maxx - minx;
- uvBounds.height = maxy - miny;
- if (maxx > 1f || minx < 0f || maxy > 1f || miny < 0f)
- {
- putResultHere.hasOutOfBoundsUVs = true;
- }
- else
- {
- putResultHere.hasOutOfBoundsUVs = false;
- }
- putResultHere.uvRect = uvBounds;
- return putResultHere.hasOutOfBoundsUVs;
- }
- public static void setSolidColor(Texture2D t, Color c){
- Color[] cs = t.GetPixels();
- for (int i = 0; i < cs.Length; i++){
- cs[i] = c;
- }
- t.SetPixels(cs);
- t.Apply();
- }
-
- public static Texture2D resampleTexture(Texture2D source, int newWidth, int newHeight){
- TextureFormat f = source.format;
- if (f == TextureFormat.ARGB32 ||
- f == TextureFormat.RGBA32 ||
- f == TextureFormat.BGRA32 ||
- f == TextureFormat.RGB24 ||
- f == TextureFormat.Alpha8 ||
- f == TextureFormat.DXT1)
- {
- Texture2D newTex = new Texture2D(newWidth,newHeight,TextureFormat.ARGB32,true);
- float w = newWidth;
- float h = newHeight;
- for (int i = 0; i < newWidth; i++){
- for (int j = 0; j < newHeight; j++){
- float u = i/w;
- float v = j/h;
- newTex.SetPixel(i,j,source.GetPixelBilinear(u,v));
- }
- }
- newTex.Apply();
- return newTex;
- } else {
- Debug.LogError("Can only resize textures in formats ARGB32, RGBA32, BGRA32, RGB24, Alpha8 or DXT. texture:" + source + " was in format: " + source.format);
- return null;
- }
- }
- class MB_Triangle{
- int submeshIdx;
- int[] vs = new int[3];
-
- public bool isSame(object obj){
- MB_Triangle tobj = (MB_Triangle) obj;
- if (vs[0] == tobj.vs[0] &&
- vs[1] == tobj.vs[1] &&
- vs[2] == tobj.vs[2] &&
- submeshIdx != tobj.submeshIdx){
- return true;
- }
- return false;
- }
-
- public bool sharesVerts(MB_Triangle obj){
- if (vs[0] == obj.vs[0] ||
- vs[0] == obj.vs[1] ||
- vs[0] == obj.vs[2]){
- if (submeshIdx != obj.submeshIdx) return true;
- }
- if (vs[1] == obj.vs[0] ||
- vs[1] == obj.vs[1] ||
- vs[1] == obj.vs[2]){
- if (submeshIdx != obj.submeshIdx) return true;
- }
- if (vs[2] == obj.vs[0] ||
- vs[2] == obj.vs[1] ||
- vs[2] == obj.vs[2]){
- if (submeshIdx != obj.submeshIdx) return true;
- }
- return false;
- }
-
- public void Initialize(int[] ts, int idx, int sIdx){
- vs[0] = ts[idx];
- vs[1] = ts[idx + 1];
- vs[2] = ts[idx + 2];
- submeshIdx = sIdx;
- Array.Sort(vs);
- }
- }
-
- public static bool AreAllSharedMaterialsDistinct(Material[] sharedMaterials){
- for (int i = 0; i < sharedMaterials.Length; i++){
- for (int j = i + 1; j < sharedMaterials.Length; j++){
- if (sharedMaterials[i] == sharedMaterials[j]){
- return false;
- }
- }
- }
- return true;
- }
-
- public static int doSubmeshesShareVertsOrTris(Mesh m, ref MeshAnalysisResult mar){
- MB_Triangle consider = new MB_Triangle();
- MB_Triangle other = new MB_Triangle();
- //cache all triangles
- int[][] tris = new int[m.subMeshCount][];
- for (int i = 0; i < m.subMeshCount; i++){
- tris[i] = m.GetTriangles(i);
- }
- bool sharesVerts = false;
- bool sharesTris = false;
- for (int i = 0; i < m.subMeshCount; i++){
- int[] smA = tris[i];
- for (int j = i+1; j < m.subMeshCount; j++){
- int[] smB = tris[j];
- for (int k = 0; k < smA.Length; k+=3){
- consider.Initialize(smA,k,i);
- for (int l = 0; l < smB.Length; l+=3){
- other.Initialize(smB,l,j);
- if (consider.isSame(other)){
- sharesTris = true;
- break;
- }
- if (consider.sharesVerts(other)){
- sharesVerts = true;
- break;
- }
- }
- }
- }
- }
- if (sharesTris){
- mar.hasOverlappingSubmeshVerts = true;
- mar.hasOverlappingSubmeshTris = true;
- return 2;
- } else if (sharesVerts){
- mar.hasOverlappingSubmeshVerts = true;
- mar.hasOverlappingSubmeshTris = false;
- return 1;
- } else {
- mar.hasOverlappingSubmeshTris = false;
- mar.hasOverlappingSubmeshVerts = false;
- return 0;
- }
- }
-
- public static bool GetBounds(GameObject go, out Bounds b){
- if (go == null){
- Debug.LogError("go paramater was null");
- b = new Bounds(Vector3.zero,Vector3.zero);
- return false;
- }
- Renderer r = GetRenderer(go);
- if (r == null){
- Debug.LogError("GetBounds must be called on an object with a Renderer");
- b = new Bounds(Vector3.zero,Vector3.zero);
- return false;
- }
- if (r is MeshRenderer){
- b = r.bounds;
- return true;
- } else if (r is SkinnedMeshRenderer){
- b = r.bounds;
- return true;
- }
- Debug.LogError("GetBounds must be called on an object with a MeshRender or a SkinnedMeshRenderer.");
- b = new Bounds(Vector3.zero,Vector3.zero);
- return false;
- }
-
- public static void Destroy(UnityEngine.Object o){
- if (Application.isPlaying){
- MonoBehaviour.Destroy(o);
- } else {
- // string p = AssetDatabase.GetAssetPath(o);
- // if (p != null && p.Equals("")) // don't try to destroy assets
- MonoBehaviour.DestroyImmediate(o,false);
- }
- }
- public static string ConvertAssetsRelativePathToFullSystemPath(string pth)
- {
- string aPth = Application.dataPath.Replace("Assets", "");
- return aPth + pth;
- }
- }
- }
|