Skip to content

Commit 1fa9a4f

Browse files
committed
fix the order the triangles are exported
* also export normals and fix the way the normals are exported, so they match the exported triangle order
1 parent 5ef6269 commit 1fa9a4f

File tree

1 file changed

+61
-14
lines changed

1 file changed

+61
-14
lines changed

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public class ModelExporter : System.IDisposable
5454
/// <summary>
5555
/// Export the mesh's UVs using layer 0.
5656
/// </summary>
57-
public void ExportUVs (MeshInfo mesh, FbxMesh fbxMesh)
57+
public void ExportUVsAndNormals (MeshInfo mesh, FbxMesh fbxMesh, int[] fbxTriangles)
5858
{
5959
// Set the normals on Layer 0.
6060
FbxLayer fbxLayer = fbxMesh.GetLayer (0 /* default layer */);
@@ -63,6 +63,27 @@ public void ExportUVs (MeshInfo mesh, FbxMesh fbxMesh)
6363
fbxLayer = fbxMesh.GetLayer (0 /* default layer */);
6464
}
6565

66+
using (var fbxLayerElement = FbxLayerElementNormal.Create (fbxMesh, "Normals"))
67+
{
68+
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByControlPoint);
69+
70+
// TODO: normals for each triangle vertex instead of averaged per control point
71+
//fbxNormalLayer.SetMappingMode (FbxLayerElement.eByPolygonVertex);
72+
73+
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eDirect);
74+
75+
// Add one normal per each vertex face index (3 per triangle)
76+
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
77+
78+
for (int n = 0; n < mesh.Normals.Length; n++)
79+
{
80+
fbxElementArray.Add (new FbxVector4 (-mesh.Normals [n] [0],
81+
mesh.Normals [n] [1],
82+
mesh.Normals [n] [2]));
83+
}
84+
fbxLayer.SetNormals (fbxLayerElement);
85+
}
86+
6687
using (var fbxLayerElement = FbxLayerElementUV.Create (fbxMesh, "UVSet"))
6788
{
6889
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygonVertex);
@@ -72,18 +93,19 @@ public void ExportUVs (MeshInfo mesh, FbxMesh fbxMesh)
7293
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
7394

7495
for (int n = 0; n < mesh.UV.Length; n++) {
75-
fbxElementArray.Add (new FbxVector2 (mesh.UV [n] [0],
76-
mesh.UV [n] [1]));
96+
fbxElementArray.Add (new FbxVector2 (mesh.UV [n] [0],
97+
mesh.UV [n] [1]));
7798
}
7899

79100
// For each face index, point to a texture uv
80101
var unityTriangles = mesh.Triangles;
81102
FbxLayerElementArray fbxIndexArray = fbxLayerElement.GetIndexArray ();
82103
fbxIndexArray.SetCount (unityTriangles.Length);
83104

84-
for (int i = 0, n = unityTriangles.Length; i < n; ++i) {
85-
fbxIndexArray.SetAt (i, unityTriangles[i]);
105+
for(int i = 0; i < fbxTriangles.Length; i++){
106+
fbxIndexArray.SetAt (i, fbxTriangles [i]);
86107
}
108+
87109
fbxLayer.SetUVs (fbxLayerElement, FbxLayerElement.EType.eTextureDiffuse);
88110
}
89111
}
@@ -201,32 +223,57 @@ public void ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene)
201223

202224
fbxMesh.InitControlPoints (NumControlPoints);
203225

226+
Dictionary<Vector3, int> ControlPointToIndex = new Dictionary<Vector3, int> ();
227+
204228
// copy control point data from Unity to FBX
205229
for (int v = 0; v < NumControlPoints; v++)
206230
{
207-
// convert from left to right-handed by negating x (Unity negates x again on import)
208-
fbxMesh.SetControlPointAt(new FbxVector4 (-meshInfo.Vertices [v].x, meshInfo.Vertices [v].y, meshInfo.Vertices [v].z), v);
209-
}
231+
if (ControlPointToIndex.ContainsKey (meshInfo.Vertices [v])) {
232+
continue;
233+
}
210234

211-
ExportUVs (meshInfo, fbxMesh);
235+
ControlPointToIndex [meshInfo.Vertices [v]] = v;
212236

213-
var fbxMaterial = ExportMaterial (meshInfo.Material, fbxScene);
214-
fbxNode.AddMaterial (fbxMaterial);
237+
fbxMesh.SetControlPointAt(new FbxVector4 (
238+
-meshInfo.Vertices [v].x,
239+
meshInfo.Vertices [v].y,
240+
meshInfo.Vertices [v].z
241+
),
242+
v);
243+
}
215244

216245
/*
217246
* Triangles have to be added in reverse order,
218247
* or else they will be inverted on import
219248
* (due to the conversion from left to right handed coords)
220249
*/
250+
int[] fbxTriangles = new int[meshInfo.Triangles.Length];
251+
int current = 0;
221252
for (int f = 0; f < meshInfo.Triangles.Length / 3; f++)
222253
{
223254
fbxMesh.BeginPolygon ();
224-
fbxMesh.AddPolygon (meshInfo.Triangles [3 * f + 2]);
225-
fbxMesh.AddPolygon (meshInfo.Triangles [3 * f + 1]);
226-
fbxMesh.AddPolygon (meshInfo.Triangles [3 * f]);
255+
256+
foreach (int val in new int[]{0,2,1}) {
257+
int tri = meshInfo.Triangles [3 * f + val];
258+
if (tri > fbxMesh.GetControlPointsCount ()) {
259+
int index = ControlPointToIndex [meshInfo.Vertices [tri]];
260+
tri = index;
261+
}
262+
fbxMesh.AddPolygon (tri);
263+
264+
// save the exported triangle order so we
265+
// properly export UVs
266+
fbxTriangles [current] = tri;
267+
current++;
268+
}
227269
fbxMesh.EndPolygon ();
228270
}
229271

272+
ExportUVsAndNormals (meshInfo, fbxMesh, fbxTriangles);
273+
274+
var fbxMaterial = ExportMaterial (meshInfo.Material, fbxScene);
275+
fbxNode.AddMaterial (fbxMaterial);
276+
230277
// set the fbxNode containing the mesh
231278
fbxNode.SetNodeAttribute (fbxMesh);
232279
fbxNode.SetShadingMode (FbxNode.EShadingMode.eWireFrame);

0 commit comments

Comments
 (0)