2017-05-08 12 views
24

DÜZENLEME: Bu yüzden Assimp dev ile kısa bir iletişimden sonra, içe aktarma işlemine işaret ettim. Ben başkasından kod devraldı gibi, o kısmı seyir düşünmüyordu:Aynalı ağ ve yanlış UV haritası çalışma zamanı dışa aktarma

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

FlipUVs yazdığını yapar, bu y ekseni üzerinde çevirir kökeni Sol üst köşesi yani. Bu yüzden şimdi modeli uygun UV ile ancak yine de yansıtılmış ağ ile alabiliyorum. Ana nesnenin ölçeği x = -1 ile ayarlanması, onu normale döndürür ve iyi görünmesini sağlar, ancak sanırım bu bir şey değildir. Yani bakmaya devam ediyorum.


Resimi gör, iki tane vinç modeli var. Soldaki, seri haline getirme ve yeniden yapılanma ile çalışma zamanında yüklenir, sağ taraftaki ise sadece sahneyi sürükleyen orijinaldir. Seri hale getirme Assimp kitaplığı ile olur.

enter image description here

kat birinci oluşturulacak olur ve sağ uv harita almak gibi görünüyor. Diğer öğeler yanlış uv haritası alırken. Her ne kadar uv haritalarının değerlerini yazdırıyor olsam da, orijinali olması gerektiği gibi eşleştiriyorlar.

Bu seri hale nasıl

, bu Assimp gelen Mesh sınıf değil, Birlik Mesh sınıfı, uygulama Serileştirme UWP inşa Windows uygulamasıdır:

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); } 
    } 

Ve bu invert süreçtir:

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'den seri hale getirilmiş değerler içeren geçici bir kapsayıcıdır. Ardından kafesleri oluşturulur:

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; 
} 

Ben de bu tür davranışlarda yol açmalıdır kodunda herhangi bir neden görmüyorum, ben değerleri yanlış olsaydı örgü vida tamamen olacağını söyleyebilirim.

Sahip olduğum fbx dosyalarının, dizinleme için üçgen yerine dörtlü olduğunu görebiliyorum.

Assimp bununla iyi gitmez mi?

+0

düşünebildiğim tek nedeni işlemek için mesh etmek foreach döngüsünden kullanılmasıdır . Bazen foreach beklendiği gibi yinelenmez. Serileştirme ve serileştirme işlemlerinde klasik for() döngüsü kullanmayı deneyin.Umarım bu, –

+0

'un yardımcı olabileceğine, belki de 3 boyutlu modelleme yazılımından farklı ayarlarla dışa aktarılabileceğini umarız? –

+0

Hata ayıklama sırasında hangi noktada istisna alıyorsunuz? –

cevap

0

Bu sorunu Assimp'ten uygun bir şekilde çözmedim.

Kullandığımız temel çözüm, nesne dönüşümünde ters çevrilmiş olan ekseni negatif olarak ölçeklemek oldu. Daha uygun bir çözüm, bütün köşeleri Birlik tarafındaki bir matrise beslemekti; böylece, köşe noktalarının konumunu düzgün bir şekilde çözecektir.

  • alın köşe liste
  • rotasyon matrisi ile çarpın
  • foreach köşe
  • atama dizisi
  • Kullanım
İlgili konular