2017-05-08 83 views
24

編輯:所以在與Assimp dev短暫接觸後,我被指向導入過程。當我接手的代碼從別人,沒想到找的那部分:鏡像網格和錯誤的UV映射運行時導出

using (var importer = new AssimpContext()) 
{ 
    scene = importer.ImportFile(file, PostProcessSteps.Triangulate | PostProcessSteps.FlipUVs | PostProcessSteps.JoinIdenticalVertices); 
} 

FlipUVs不正是它說,它翻轉在y軸,使原點現在左上角。所以現在我能夠得到具有適當UV的模型,但仍然是鏡像網格。設置縮放x = -1的父對象將其翻轉回正常狀態,並使其看起來很好,但我想這不意味着。所以我一直在尋找。


查看圖片,有兩種起重機型號。左邊的一個是在運行時通過序列化和重建加載的,而右邊的是原始的拖動到現場。 序列化發生在Assimp庫中。

enter image description here

地板恰好是創建第一,似乎得到正確的UV貼圖。而其他項目得到錯誤的UV地圖。雖然我印刷的uv地圖的價值,他們似乎匹配原來的,因爲他們應該。

這是如何序列化,這是來自Assimp網類,而不是統一網格類,應用程序序列化是建立在UWP Windows應用程序:

private static void SerializeMeshes(BinaryWriter writer, IEnumerable<Mesh> meshes) 
    { 
     foreach (Mesh mesh in meshes) 
     { 
      ICollection<int> triangles = MeshLoadTriangles(mesh); 
      MeshSerializeHeader(writer, mesh.Name, mesh.VertexCount, triangles.Count, mesh.MaterialIndex); 
      MeshSerializeVertices(writer, mesh.Vertices); 
      MeshSerializeUVCoordinate(writer, mesh.TextureCoordinateChannels); 
      MeshSerializeTriangleIndices(writer, triangles);      
     } 
    } 

    private static void MeshSerializeUVCoordinate(BinaryWriter writer, List<Vector3D>[] textureCoordinateChannels) 
    { 
     // get first channel and serialize to writer. Discard z channel 
     // This is Vector3D since happening outside Unity 
     List<Vector3D> list = textureCoordinateChannels[0]; 
     foreach (Vector3D v in list) 
     { 
      float x = v.X; 
      float y = v.Y; 
      writer.Write(x); 
      writer.Write(y); 
     } 
    } 
    private static void MeshSerializeVertices(BinaryWriter writer, IEnumerable<Vector3D> vertices) 
    { 
     foreach (Vector3D vertex in vertices) 
     { 
      Vector3D temp = vertex; 
      writer.Write(temp.X); 
      writer.Write(temp.Y); 
      writer.Write(temp.Z); 
     } 
    } 
    private static void MeshSerializeTriangleIndices(BinaryWriter writer, IEnumerable<int> triangleIndices) 
    { 
      foreach (int index in triangleIndices) { writer.Write(index); } 
    } 

這是反轉的過程:

private static void DeserializeMeshes(BinaryReader reader, SceneGraph scene) 
    {   
     MeshData[] meshes = new MeshData[scene.meshCount]; 
     for (int i = 0; i < scene.meshCount; i++) 
     { 
      meshes[i] = new MeshData(); 
      MeshReadHeader(reader, meshes[i]); 
      MeshReadVertices(reader, meshes[i]); 
      MeshReadUVCoordinate(reader, meshes[i]); 
      MeshReadTriangleIndices(reader, meshes[i]); 
     } 
     scene.meshes = meshes as IEnumerable<MeshData>; 
    } 
private static void MeshReadUVCoordinate(BinaryReader reader, MeshData meshData) 
    { 
     bool hasUv = reader.ReadBoolean(); 
     if(hasUv == false) { return; } 
     Vector2[] uvs = new Vector2[meshData.vertexCount]; 
     for (int i = 0; i < uvs.Length; i++) 
     { 
      uvs[i] = new Vector2(); 
      uvs[i].x = reader.ReadSingle(); 
      uvs[i].y = reader.ReadSingle(); 
     } 
     meshData.uvs = uvs; 
    } 
    private static void MeshReadHeader(BinaryReader reader, MeshData meshData) 
    { 
     meshData.name = reader.ReadString(); 
     meshData.vertexCount = reader.ReadInt32(); 
     meshData.triangleCount = reader.ReadInt32(); 
     meshData.materialIndex = reader.ReadInt32(); 
    } 
    private static void MeshReadVertices(BinaryReader reader, MeshData meshData) 
    { 
     Vector3[] vertices = new Vector3[meshData.vertexCount]; 

     for (int i = 0; i < vertices.Length; i++) 
     { 
      vertices[i] = new Vector3(); 
      vertices[i].x = reader.ReadSingle(); 
      vertices[i].y = reader.ReadSingle(); 
      vertices[i].z = reader.ReadSingle(); 
     } 
     meshData.vertices = vertices; 
    } 
    private static void MeshReadTriangleIndices(BinaryReader reader, MeshData meshData) 
    { 
     int[] triangleIndices = new int[meshData.triangleCount]; 

     for (int i = 0; i < triangleIndices.Length; i++) 
     { 
      triangleIndices[i] = reader.ReadInt32(); 
     } 
     meshData.triangles = triangleIndices; 
    } 

MeshData只是一個臨時容器,具有來自fbx的反序列化值。 然後,創建網格:

private static Mesh[] CreateMeshes(SceneGraph scene) 
{ 
    Mesh[] meshes = new Mesh[scene.meshCount]; 
    int index = 0; 
    foreach (MeshData meshData in scene.meshes) 
    { 
     meshes[index] = new Mesh();   
     Vector3[] vec = meshData.vertices; 
     meshes[index].vertices = vec; 
     meshes[index].triangles = meshData.triangles; 
     meshes[index].uv = meshData.uvs; 
     meshes[index].normals = meshData.normals; 
     meshes[index].RecalculateNormals(); 
     index++; 
    } 
    return meshes; 
} 

我沒有看到應該導致這種行爲的代碼的任何原因,我會說這將完全擰網,如果值是錯誤的。

我可以看到我的fbx文件是使用四邊形代替三角形進行索引。

難道是Assimp對此不好嗎?

+0

我能想到的唯一原因是使用foreach循環的。有時候foreach不會像預期的那樣迭代。嘗試在( - )循環中使用經典的 - 序列化和反序列化。希望這有助於 –

+0

也許這些從3D建模軟件導出不同的設置? –

+0

在哪一點你調試時得到異常? –

回答

0

我沒有從Assimp以正確的方式解決問題。

我們使用的基本解決方案是負向縮放在對象轉換中翻轉的軸。

更合適的解決方案是將所有頂點提供給Unity側的矩陣,以便正確解析頂點的位置。

  • 獲取頂點列表
  • 與旋轉矩陣
  • 的foreach頂點乘
  • 指定數組網
  • 採用網狀渲染