@@ -54,7 +54,7 @@ public class ModelExporter : System.IDisposable
54
54
/// <summary>
55
55
/// Export the mesh's UVs using layer 0.
56
56
/// </summary>
57
- public void ExportUVs ( MeshInfo mesh , FbxMesh fbxMesh )
57
+ public void ExportUVsAndNormals ( MeshInfo mesh , FbxMesh fbxMesh , int [ ] fbxTriangles )
58
58
{
59
59
// Set the normals on Layer 0.
60
60
FbxLayer fbxLayer = fbxMesh . GetLayer ( 0 /* default layer */ ) ;
@@ -63,6 +63,27 @@ public void ExportUVs (MeshInfo mesh, FbxMesh fbxMesh)
63
63
fbxLayer = fbxMesh . GetLayer ( 0 /* default layer */ ) ;
64
64
}
65
65
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
+
66
87
using ( var fbxLayerElement = FbxLayerElementUV . Create ( fbxMesh , "UVSet" ) )
67
88
{
68
89
fbxLayerElement . SetMappingMode ( FbxLayerElement . EMappingMode . eByPolygonVertex ) ;
@@ -72,18 +93,19 @@ public void ExportUVs (MeshInfo mesh, FbxMesh fbxMesh)
72
93
FbxLayerElementArray fbxElementArray = fbxLayerElement . GetDirectArray ( ) ;
73
94
74
95
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 ] ) ) ;
77
98
}
78
99
79
100
// For each face index, point to a texture uv
80
101
var unityTriangles = mesh . Triangles ;
81
102
FbxLayerElementArray fbxIndexArray = fbxLayerElement . GetIndexArray ( ) ;
82
103
fbxIndexArray . SetCount ( unityTriangles . Length ) ;
83
104
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 ] ) ;
86
107
}
108
+
87
109
fbxLayer . SetUVs ( fbxLayerElement , FbxLayerElement . EType . eTextureDiffuse ) ;
88
110
}
89
111
}
@@ -201,32 +223,57 @@ public void ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene)
201
223
202
224
fbxMesh . InitControlPoints ( NumControlPoints ) ;
203
225
226
+ Dictionary < Vector3 , int > ControlPointToIndex = new Dictionary < Vector3 , int > ( ) ;
227
+
204
228
// copy control point data from Unity to FBX
205
229
for ( int v = 0 ; v < NumControlPoints ; v ++ )
206
230
{
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
+ }
210
234
211
- ExportUVs ( meshInfo , fbxMesh ) ;
235
+ ControlPointToIndex [ meshInfo . Vertices [ v ] ] = v ;
212
236
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
+ }
215
244
216
245
/*
217
246
* Triangles have to be added in reverse order,
218
247
* or else they will be inverted on import
219
248
* (due to the conversion from left to right handed coords)
220
249
*/
250
+ int [ ] fbxTriangles = new int [ meshInfo . Triangles . Length ] ;
251
+ int current = 0 ;
221
252
for ( int f = 0 ; f < meshInfo . Triangles . Length / 3 ; f ++ )
222
253
{
223
254
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
+ }
227
269
fbxMesh . EndPolygon ( ) ;
228
270
}
229
271
272
+ ExportUVsAndNormals ( meshInfo , fbxMesh , fbxTriangles ) ;
273
+
274
+ var fbxMaterial = ExportMaterial ( meshInfo . Material , fbxScene ) ;
275
+ fbxNode . AddMaterial ( fbxMaterial ) ;
276
+
230
277
// set the fbxNode containing the mesh
231
278
fbxNode . SetNodeAttribute ( fbxMesh ) ;
232
279
fbxNode . SetShadingMode ( FbxNode . EShadingMode . eWireFrame ) ;
0 commit comments