Advertisement
Guest User

Jon Martin

a guest
Jan 14th, 2011
482
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.56 KB | None | 0 0
  1. //OBJ import for Unity3d 2/3
  2. //OBJ.cs by bartek drozdz of http://www.everyday3d.com (ammendments by Jon Martin of jon-martin.com & fusedworks.com)
  3.  
  4. using UnityEngine;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7.  
  8. public class GeometryBuffer {
  9.  
  10.     private List<ObjectData> objects;
  11.     public List<Vector3> vertices;
  12.     public List<Vector2> uvs;
  13.     public List<Vector3> normals;
  14.    
  15.     private ObjectData current;
  16.     private class ObjectData {
  17.         public string name;
  18.         public List<GroupData> groups;
  19.         public List<FaceIndices> allFaces;
  20.         public ObjectData() {
  21.             groups = new List<GroupData>();
  22.             allFaces = new List<FaceIndices>();
  23.         }
  24.     }
  25.    
  26.     private GroupData curgr;
  27.     private class GroupData {
  28.         public string name;
  29.         public string materialName;
  30.         public List<FaceIndices> faces;
  31.         public GroupData() {
  32.             faces = new List<FaceIndices>();
  33.         }
  34.         public bool isEmpty { get { return faces.Count == 0; } }
  35.     }
  36.    
  37.     public GeometryBuffer() {
  38.         objects = new List<ObjectData>();
  39.         ObjectData d = new ObjectData();
  40.         d.name = "default";
  41.         objects.Add(d);
  42.         current = d;
  43.        
  44.         GroupData g = new GroupData();
  45.         g.name = "default";
  46.         // OBJ.cs ALTERATION3: added to help with missing material libraries see
  47.         g.materialName = "default";    
  48.         d.groups.Add(g);
  49.         curgr = g;
  50.        
  51.         vertices = new List<Vector3>();
  52.         uvs = new List<Vector2>();
  53.         normals = new List<Vector3>();
  54.     }
  55.    
  56.     public void PushObject(string name) {
  57.         //Debug.Log("Adding new object " + name + ". Current is empty: " + isEmpty);
  58.         if(isEmpty) objects.Remove(current);
  59.        
  60.         ObjectData n = new ObjectData();
  61.         n.name = name;
  62.         objects.Add(n);
  63.        
  64.         GroupData g = new GroupData();
  65.         g.name = "default";
  66.         n.groups.Add(g);
  67.        
  68.         curgr = g;
  69.         current = n;
  70.     }
  71.    
  72.     public void PushGroup(string name) {
  73.         if(curgr.isEmpty) current.groups.Remove(curgr);
  74.         GroupData g = new GroupData();
  75.         g.name = name;
  76.         // OBJ.cs ALTERATION3: added to help with missing material libraries see
  77.         g.materialName = "default";    
  78.         current.groups.Add(g);
  79.         curgr = g;
  80.     }
  81.    
  82.     public void PushMaterialName(string name) {
  83.         Debug.Log("Pushing new material " + name + " with curgr.empty=" + curgr.isEmpty);
  84.         if(!curgr.isEmpty) PushGroup(name);
  85.         if(curgr.name == "default") curgr.name = name;
  86.         curgr.materialName = name;
  87.     }
  88.    
  89.     //OBJ.cs ALTERATION 4:- Lets say they moved the material library retrieve material names that need to be set up.
  90.     public string[] ReturnMaterialNames() {
  91.         string[] EmptyMaterials;
  92.         int i=0;
  93.         foreach(ObjectData od in objects) {
  94.             i+=od.groups.Count;
  95.         }
  96.         EmptyMaterials = new string[i];
  97.         i=0;
  98.         foreach(ObjectData od in objects) {
  99.             foreach(GroupData gd in od.groups) {
  100.                 EmptyMaterials[i]=gd.materialName;
  101.             }
  102.         }      
  103.         return EmptyMaterials;
  104.     }
  105.    
  106.    
  107.     public void PushVertex(Vector3 v) {
  108.         vertices.Add(v);
  109.     }
  110.    
  111.     public void PushUV(Vector2 v) {
  112.         uvs.Add(v);
  113.     }
  114.    
  115.     public void PushNormal(Vector3 v) {
  116.         normals.Add(v);
  117.     }
  118.    
  119.     public void PushFace(FaceIndices f) {
  120.         curgr.faces.Add(f);
  121.         current.allFaces.Add(f);
  122.     }
  123.    
  124.     public void Trace() {
  125.         Debug.Log("OBJ has " + objects.Count + " object(s)");
  126.         Debug.Log("OBJ has " + vertices.Count + " vertice(s)");
  127.         Debug.Log("OBJ has " + uvs.Count + " uv(s)");
  128.         Debug.Log("OBJ has " + normals.Count + " normal(s)");
  129.         foreach(ObjectData od in objects) {
  130.             Debug.Log(od.name + " has " + od.groups.Count + " group(s)");
  131.             foreach(GroupData gd in od.groups) {
  132.                 Debug.Log(od.name + "/" + gd.name + " has " + gd.faces.Count + " faces(s)");
  133.             }
  134.         }
  135.        
  136.     }
  137.    
  138.     public int numObjects { get { return objects.Count; } }
  139.     public bool isEmpty { get { return vertices.Count == 0; } }
  140.     public bool hasUVs { get { return uvs.Count > 0; } }
  141.     public bool hasNormals { get { return normals.Count > 0; } }
  142.    
  143.     public void PopulateMeshes(GameObject[] gs, Dictionary<string, Material> mats) {
  144.         if(gs.Length != numObjects) {
  145.                 return; // Should not happen unless obj file is corrupt...
  146.             }
  147.         for(int i = 0; i < gs.Length; i++) {
  148.             ObjectData od = objects[i];
  149.            
  150.             if(od.name != "default") gs[i].name = od.name;
  151.            
  152.             Vector3[] tvertices = new Vector3[od.allFaces.Count];
  153.             Vector2[] tuvs = new Vector2[od.allFaces.Count];
  154.             Vector3[] tnormals = new Vector3[od.allFaces.Count];
  155.        
  156.             int k = 0;
  157.             foreach(FaceIndices fi in od.allFaces) {
  158.                 tvertices[k] = vertices[fi.vi];
  159.                 if(hasUVs) tuvs[k] = uvs[fi.vu];
  160.                 if(hasNormals) tnormals[k] = normals[fi.vn];
  161.                 k++;
  162.             }
  163.        
  164.             Mesh m = (gs[i].GetComponent(typeof(MeshFilter)) as MeshFilter).mesh;
  165.             m.vertices = tvertices;
  166.             if(hasUVs) m.uv = tuvs;
  167.             if(hasNormals) m.normals = tnormals;
  168.            
  169.             if(od.groups.Count == 1) {
  170.                 GroupData gd = od.groups[0];
  171.                
  172.                 gs[i].renderer.material = mats[gd.materialName];
  173.                
  174.                 //Alteration 6 ADDED TO NAME MATERIALS
  175.                 gs[i].renderer.material.name = gd.materialName;
  176.                
  177.                 int[] triangles = new int[gd.faces.Count];
  178.                 for(int j = 0; j < triangles.Length; j++) triangles[j] = j;
  179.                
  180.                 m.triangles = triangles;
  181.                
  182.                 //Alteration 5 Added for those OBJ file without normals
  183.                 if(!hasNormals) {
  184.                     m.RecalculateNormals();
  185.                 }
  186.                 CalculateTangents(m);
  187.                
  188.             } else {
  189.                 int gl = od.groups.Count;
  190.                 Material[] sml = new Material[gl];
  191.                 m.subMeshCount = gl;
  192.                 int c = 0;
  193.                
  194.                 for(int j = 0; j < gl; j++) {
  195.                     sml[j] = mats[od.groups[j].materialName];
  196.                    
  197.                     //Alteration 6 ADDED TO NAME MATERIALS
  198.                     sml[j].name = od.groups[j].materialName;
  199.                    
  200.                     int[] triangles = new int[od.groups[j].faces.Count];
  201.                     int l = od.groups[j].faces.Count + c;
  202.                     int s = 0;
  203.                     for(; c < l; c++, s++) triangles[s] = c;
  204.                     m.SetTriangles(triangles, j);
  205.                     //Alteration 5 Added for those OBJ file without normals
  206.                     if(!hasNormals) {
  207.                         m.RecalculateNormals();
  208.                     }
  209.                     CalculateTangents(m);
  210.                 }
  211.                 gs[i].renderer.materials = sml;
  212.             }
  213.         }
  214.     }
  215.  
  216.     //Alteration 7 Added CalculateTangents Function to cater for bumpmaps on the mesh etc.
  217.     public void CalculateTangents(Mesh mesh) {
  218.         int triangleCount = mesh.triangles.Length / 3;
  219.         int vertexCount = mesh.vertices.Length;
  220.  
  221.         Vector3[] tan1 = new Vector3[vertexCount];
  222.         Vector3[] tan2 = new Vector3[vertexCount];
  223.         Vector4[] tangents = new Vector4[vertexCount];
  224.  
  225.         for(long a = 0; a < triangleCount; a+=3) {
  226.             long i1 = mesh.triangles[a+0];
  227.             long i2 = mesh.triangles[a+1];
  228.             long i3 = mesh.triangles[a+2];
  229.             Vector3 v1 = mesh.vertices[i1];
  230.             Vector3 v2 = mesh.vertices[i2];
  231.             Vector3 v3 = mesh.vertices[i3];
  232.             Vector2 w1 = mesh.uv[i1];
  233.             Vector2 w2 = mesh.uv[i2];
  234.             Vector2 w3 = mesh.uv[i3];
  235.  
  236.             float x1 = v2.x - v1.x;
  237.             float x2 = v3.x - v1.x;
  238.             float y1 = v2.y - v1.y;
  239.             float y2 = v3.y - v1.y;
  240.             float z1 = v2.z - v1.z;
  241.             float z2 = v3.z - v1.z;
  242.  
  243.             float s1 = w2.x - w1.x;
  244.             float s2 = w3.x - w1.x;
  245.             float t1 = w2.y - w1.y;
  246.             float t2 = w3.y - w1.y;
  247.  
  248.             float r = 1.0f / (s1 * t2 - s2 * t1);
  249.  
  250.             Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
  251.             Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
  252.  
  253.             tan1[i1] += sdir;
  254.             tan1[i2] += sdir;
  255.             tan1[i3] += sdir;
  256.  
  257.             tan2[i1] += tdir;
  258.             tan2[i2] += tdir;
  259.             tan2[i3] += tdir;
  260.         }
  261.  
  262.         for (long a = 0; a < vertexCount; ++a)  {
  263.             Vector3 n = mesh.normals[a];
  264.             Vector3 t = tan1[a];
  265.             Vector3 tmp = (t - n * Vector3.Dot(n, t)).normalized;
  266.             tangents[a] = new Vector4(tmp.x, tmp.y, tmp.z);
  267.             tangents[a].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
  268.         }
  269.         mesh.tangents = tangents;
  270.     }
  271.    
  272. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement