2017-05-08 7 views
24

編集:Assimp開発者と簡単に連絡した後、私はインポートプロセスを指摘しました。私は他の誰かからのコードを引き継いだとして、私はその部分を見ているとは思いませんでした:ミラーメッシュと間違ったUVマップ実行時のエクスポート

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

FlipUVsそれが言うまさにませ起源は今、左上隅であるので、それはy軸に反転します。だから、私は適切なUVでモデルを得ることができますが、それでもまだメッシュが鏡になっています。スケールx = -1で親オブジェクトを設定すると、それが通常の状態に戻ってきれいに見えるようになりますが、これは意味がありません。だから私は探し続けている。


写真を参照すると、2つのクレーンモデルがあります。左のものは実行時に直列化と再構成によってロードされ、右のものはシーンにドラッグされた元のものです。 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が期待どおりに反復しないことがあります。シリアライズとデシリアライゼーションの両方でclassic for()ループを使用してみてください。これが役に立ったら –

+0

多分これらは3Dモデリングソフトウェアから別の設定でエクスポートできますか? –

+0

どの時点でデバッグ中に例外が発生していますか? –

答えて

0

私はAssimpから適切な方法で問題を解決しませんでした。

私たちが使用した基本的な解決策は、オブジェクト変換で反転された軸を負の値にスケールすることでした。

さらに適切な解決策は、Unity側のすべての頂点を行列に供給して、頂点の位置を適切に解決することでした。

  • 取得頂点リスト
  • foreachの頂点乗算回転行列で
  • 使用をメッシュにする
  • 割り当て配列は、私は考えることができ
関連する問題