2017-05-08 9 views
24

편집 : 따라서 Assimp 개발자와 짧은 연락을 한 후에 가져 오기 과정을 가리켰습니다. 내가 다른 사람의 코드를 인수, 나는 그 부분을보고 생각하지 않았다 :미러 된 메쉬와 잘못된 UV ​​맵 런타임 내보내기

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

FlipUVs가 말하는 정확히 않습니다, 그것은 y 축에 대칭 이동 기원은 지금 왼쪽 상단 그래서. 그래서 지금은 적절한 자외선으로 모델을 얻을 수 있지만 여전히 메쉬를 미러링 할 수 있습니다. 눈금 x = -1로 부모 개체를 설정하면 정상으로 되돌려 보이고 멋지게 보이지만 이것이 의도되지는 않습니다. 그래서 나는 계속 찾고있다.


두 개의 크레인 모델이 있습니다. 왼쪽에있는 것은 런타임에 직렬화 및 재구성을 통해로드되는 반면 오른쪽은 원래 장면으로 간단히 드래그됩니다. Assimp 라이브러리에서 직렬화가 발생합니다.

enter image description here

바닥은 처음 생성 될 일이 오른쪽 UV 맵을 얻을 것으로 보인다. 다른 항목은 잘못된 uv 맵을 얻습니다. 내가 uv지도의 값을 인쇄하고 있지만 원래 맵과 일치하는 것처럼 보입니다.

이 직렬화하는 방법입니다

, 이것은 Assimp에서 메시 클래스가 아닌 유니티 메쉬 클래스, 응용 프로그램의 직렬화는 UWP에 내장 된 윈도우 응용 프로그램입니다 :

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가 예상대로 반복하지 않습니다. 직렬화와 비 직렬화 모두에서 고전적인 for() 루프를 사용해보십시오.희망이 도움이 –

+0

어쩌면 이들이 어디에서 3D 모델링 소프트웨어에서 다른 설정으로 수출? –

+0

디버깅 중 어떤 시점에서 예외가 발생합니까? –

답변

0

저는 Assimp에서 적절한 방법으로 문제를 해결하지 못했습니다.

우리가 사용한 기본 솔루션은 객체 변환에서 뒤집힌 축을 음의 축척으로 조정하는 것이 었습니다.

보다 적절한 해결 방법은 모든 정점을 Unity 측의 행렬에 공급하여 정점의 위치를 ​​올바르게 결정하는 것입니다.

  • 가져 오기 정점 목록
  • 회전 행렬 곱셈
  • foreach는 정점
  • 할당 배열이
  • 사용이