rabidus-test/Assets/Scripts/PostImportTool.cs

381 lines
9.8 KiB
C#

#if UNITY_EDITOR
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System;
using Random = UnityEngine.Random;
using System.Globalization;
public class PostImportTool : AssetPostprocessor
{
class Section
{
public int Offset;
public int NumIndices;
public int Materialindex;
public string MaterialName;
public Material Mat;
}
class MeshBinding
{
public Mesh mesh;
public MeshRenderer renderer;
}
void GetFloatsFromLine( string Line, ref List<float> Floats, GameObject gameobject )
{
Floats.Clear();
string[] Tokens = Line.Split(new char[]{ ' ' } );
for( int u = 1; u < Tokens.Length; u++ )
{
try
{
CultureInfo ci = (CultureInfo)CultureInfo.InvariantCulture.Clone();
ci.NumberFormat.CurrencyDecimalSeparator = ".";
float Val = float.Parse( Tokens[u], ci.NumberFormat);
Floats.Add( Val );
}
catch( FormatException e )
{
Debug.LogError( "float.Parse failed in " + gameobject.name + " input=" + Tokens[u] + " exception=" + e.Message );
}
}
}
void GetIntsFromLine( string Line, ref List<int> Ints, GameObject gameobject )
{
Ints.Clear();
string[] Tokens = Line.Split(new char[]{ ' ', '/' } );
for( int u = 1; u < Tokens.Length; u++ )
{
try
{
int Val = int.Parse( Tokens[u] );
Ints.Add( Val );
}
catch( FormatException e )
{
Debug.LogError( "int.Parse failed in " + gameobject.name + " input=" + Tokens[u] + " exception=" + e.Message );
}
}
}
private void OnPostprocessModel(GameObject gameobject)
{
UnityEditor.ModelImporter importer = this.assetImporter as UnityEditor.ModelImporter;
string Path = importer.assetPath;
if( !Path.Contains( ".obj" ) )
return;
string OBJFile = File.ReadAllText( Path );
List<float> Floats = new List<float>();
List<int> Ints = new List<int>();
List<Vector3> Vertices = new List<Vector3>();
List<Color> Colors = new List<Color>();
List<Vector2> Texcoords0 = new List<Vector2>();
List<Vector2> Texcoords1 = new List<Vector2>();
List<Vector3> Normals = new List<Vector3>();
List<Vector4> Tangents = new List<Vector4>();
bool ReplaceNormals = true;
List<int> Indices = new List<int>();
List<Section> Sections = new List<Section>();
string[] Lines = OBJFile.Split( new char[]{ '\n' } );
for(int i=0; i<Lines.Length; i++ )
{
string Line = Lines[i];
if (Line.StartsWith("v "))
{
string[] Tokens = Line.Split(new char[]{ ' ' } );
Floats.Clear();
for(int u=1; u<Tokens.Length; u++ )//0 should be "v"
{
try
{
CultureInfo ci = (CultureInfo)CultureInfo.InvariantCulture.Clone();
ci.NumberFormat.CurrencyDecimalSeparator = ".";
float Val = float.Parse( Tokens[u], ci.NumberFormat);
Floats.Add( Val );
}
catch(FormatException e )
{
Debug.LogError( "float.Parse failed for verts in " + gameobject.name + " input=" + Tokens[u] + " exception=" + e.Message );
}
}
if ( Floats.Count >= 3)
Vertices.Add( new Vector3( Floats[0], Floats[1], Floats[2] ) );
else
Vertices.Add( new Vector3( 0, 0, 0 ) );
if ( Floats.Count == 7 )
{
Colors.Add( new Color( Floats[3], Floats[4], Floats[5], Floats[6] ) );
}
}
else if( Line.StartsWith( "vt " ) )
{
GetFloatsFromLine( Line, ref Floats, gameobject );
if( Floats.Count == 2 )
{
Texcoords0.Add( new Vector2( Floats[0], Floats[1] ) );
}
else
Texcoords0.Add( new Vector2( 0, 0 ) );
}
else if( Line.StartsWith( "vt1 " ) )
{
GetFloatsFromLine( Line, ref Floats, gameobject );
if( Floats.Count == 2 )
{
Texcoords1.Add( new Vector2( Floats[0], Floats[1] ) );
}
else
Texcoords1.Add( new Vector2( 0, 0 ) );
}
else if( ReplaceNormals && Line.StartsWith( "vn " ) )
{
GetFloatsFromLine( Line, ref Floats, gameobject );
if( Floats.Count == 3 )
{
Normals.Add( new Vector3( Floats[0], Floats[1], Floats[2] ) );
}
else
Normals.Add( new Vector3( 0, 0, 0 ) );
}
else if( Line.StartsWith( "tan " ) )
{
GetFloatsFromLine( Line, ref Floats, gameobject );
if( Floats.Count == 4 )
{
Tangents.Add( new Vector4( Floats[0], Floats[1], Floats[2], Floats[3] ) );
}
else
Normals.Add( new Vector4( 0, 0, 0, 0 ) );
}
else if( Line.StartsWith( "f " ) )
{
GetIntsFromLine( Line, ref Ints, gameobject );
if( Ints.Count == 9 )
{
Indices.Add( Ints[0] - 1 );
Indices.Add( Ints[3] - 1 );
Indices.Add( Ints[6] - 1 );
}
}
//"#Section %d Offset %d NumIndices %d MaterialIndex %d %s\n"
if( Line.StartsWith( "#Section " ) )
{
string[] Tokens = Line.Split(new char[]{ ' ' } );
if( Tokens.Length == 9 )
{
Section NewSection = new Section();
NewSection.Offset = int.Parse( Tokens[3] );
NewSection.NumIndices = int.Parse( Tokens[5] );
//NewSection.Materialindex = int.Parse( Tokens[7] );
NewSection.MaterialName = Tokens[8].Trim();
Sections.Add( NewSection );
}
}
}
MeshBinding[] MeshArray = GetMeshes( gameobject);
if( MeshArray.Length == 0 )
return;
MeshBinding Binding = MeshArray[0];
Mesh m = Binding.mesh;
if( m.vertices.Length != Vertices.Count )
{
Debug.LogError( "m.vertices.Length != Vertices.Count for " + gameobject.name );
}
if ( m.GetIndices( 0 ).Length != Indices.Count )
{
Debug.LogError( "m.GetIndices( 0 ).Length != Indices.Count for " + gameobject.name );
}
m.SetIndices( Indices.ToArray(), MeshTopology.Triangles, 0 );
m.vertices = Vertices.ToArray();
if( Texcoords0.Count != m.uv.Length )
{
Debug.LogError( "Texcoords0.Count != m.uv.Length for " + gameobject.name );
}
m.uv = Texcoords0.ToArray();
if( Colors.Count > 0 )
{
if( m.vertices.Length != Colors.Count )
{
Debug.LogError( " Mesh vertex count != color count for " + gameobject.name );
}
else
{
m.colors = Colors.ToArray();
}
}
if ( Texcoords1.Count > 0 )
{
if( m.vertices.Length != Texcoords1.Count )
{
Debug.LogError( " Mesh vertex count != Texcoords1 count for " + gameobject.name );
}
else
{
m.uv2 = Texcoords1.ToArray();
}
}
if( Sections.Count > 1 )
{
SetupSubmeshes( m, Sections.ToArray(), gameobject.name );
}
Material[] UsedMaterials = GetSectionMaterials( Sections.ToArray() );
Binding.renderer.sharedMaterials = UsedMaterials;
if( ReplaceNormals && Normals.Count > 0 )
{
if( m.vertices.Length != Normals.Count )
{
Debug.LogError( " Mesh vertex count != Texcoords1 count " + gameobject.name );
}
else
{
m.normals = Normals.ToArray();
}
}
if( Tangents.Count > 0 )
{
if ( m.tangents.Length == 0 || m.tangents.Length == Tangents.Count )
{
m.tangents = Tangents.ToArray();
}
else
{
Debug.LogError( " Mesh vertex count != Tangents count " + gameobject.name );
}
}
m.RecalculateBounds();
}
Material[] GetSectionMaterials( Section[] sections )
{
Material[] AllMaterials = UnityEngine.Resources.FindObjectsOfTypeAll<Material>();
Material[] UsedMaterials = new Material[sections.Length];
for( int i = 0; i < sections.Length; i++ )
{
Section s = sections[i];
if( !s.MaterialName.Equals( "None" ) )
{
for( int m = 0; m < AllMaterials.Length; m++ )
{
if( AllMaterials[m].name.Equals( s.MaterialName ) )
{
s.Mat = AllMaterials[m];
UsedMaterials[i] = s.Mat;
break;
}
}
}
}
return UsedMaterials;
}
void SetupSubmeshes( Mesh mesh, Section[] sections, String Name )
{
int[] AllIndices = mesh.GetIndices( 0 );
mesh.subMeshCount = sections.Length;
for(int i = 0; i<sections.Length; i++ )
{
Section s = sections[i];
int[] SectionIndices = new int[ s.NumIndices ];
for(int u=0; u< s.NumIndices; u++ )
{
if ( s.Offset + u < AllIndices.Length)
SectionIndices[u] = AllIndices[ s.Offset + u ];
else
{
Debug.LogError( "AllIndices is too small for " + Name );
break;
}
}
mesh.SetIndices( SectionIndices, MeshTopology.Triangles, i );
}
}
MeshBinding[] GetMeshes( GameObject gameObject )
{
List<MeshBinding> MeshArray = new List<MeshBinding>();
MeshFilter[] MFArray = gameObject.GetComponentsInChildren<MeshFilter>();
if( MFArray != null )
{
for( int i = 0; i < MFArray.Length; i++ )
{
MeshFilter MF = MFArray[i];
Mesh m = MFArray[i].sharedMesh;
MeshBinding NewMeshBinding = new MeshBinding();
NewMeshBinding.mesh = m;
NewMeshBinding.renderer = MF.gameObject.GetComponent<MeshRenderer>();
MeshArray.Add( NewMeshBinding );
}
}
return MeshArray.ToArray();
}
[MenuItem( "RE/PrintMesh" )]
static void PrintMesh()
{
if( Selection.gameObjects.Length == 0 )
return;
GameObject go = Selection.gameObjects[0];
MeshFilter MF = go.GetComponent<MeshFilter>();
Mesh mesh = MF.sharedMesh;
string Data = "";
Data += "Vertices " + mesh.vertexCount + "\n";
for( int i = 0; i < mesh.subMeshCount; i++ )
{
int[] Indices = mesh.GetTriangles( i );
uint BaseVertex = mesh.GetBaseVertex( i );
Data += "Section " + i + " Indices " + Indices.Length + " BaseVertex " + BaseVertex + "\n";
}
Vector3[] vertices = mesh.vertices;
for( int i = 0; i < vertices.Length; i++ )
{
Data += "v " + vertices[i].x + " " + vertices[i].y + " " + vertices[i].z + "\n";
}
for( int i = 0; i < mesh.subMeshCount; i++ )
{
int[] Indices = mesh.GetTriangles( i );
Data += "Section " + i + "\n";
for( int u = 0; u < Indices.Length; u += 3 )
{
int I1 = Indices[ u ] + 1;
int I2 = Indices[ u + 1] + 1;
int I3 = Indices[ u + 2] + 1;
//Debug.Log( "f " + I1 + " " + I2 + " " + I3 );
Data += "f " + I3 + " " + I2 + " " + I1 + "\n";
}
}
File.WriteAllText( "C:/UnrealToUnity/Out.txt", Data );
}
}
#endif