Skip to content

Commit c37339f

Browse files
authored
Merge pull request #221 from Unity-Technologies/UNI-30401-fix-exporting-without-normals-error
UNI-30401 handle missing normals, binormals, tangents, vertex colors
2 parents f20c664 + b092608 commit c37339f

File tree

1 file changed

+106
-68
lines changed

1 file changed

+106
-68
lines changed

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 106 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -192,91 +192,96 @@ private bool ExportComponentAttributes (MeshInfo mesh, FbxMesh fbxMesh, int[] un
192192
// Set the normals on Layer 0.
193193
FbxLayer fbxLayer = GetOrCreateLayer(fbxMesh);
194194

195-
using (var fbxLayerElement = FbxLayerElementNormal.Create (fbxMesh, "Normals")) {
196-
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygonVertex);
197-
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eDirect);
195+
if (mesh.HasValidNormals(unmergedTriangles.Length)) {
196+
using (var fbxLayerElement = FbxLayerElementNormal.Create (fbxMesh, "Normals")) {
197+
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygonVertex);
198+
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eDirect);
198199

199-
// Add one normal per each vertex face index (3 per triangle)
200-
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
200+
// Add one normal per each vertex face index (3 per triangle)
201+
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
201202

202-
for (int n = 0; n < unmergedTriangles.Length; n++) {
203-
int unityTriangle = unmergedTriangles [n];
204-
fbxElementArray.Add (ConvertNormalToRightHanded (mesh.Normals [unityTriangle]));
205-
}
203+
for (int n = 0; n < unmergedTriangles.Length; n++) {
204+
int unityTriangle = unmergedTriangles [n];
205+
fbxElementArray.Add (ConvertNormalToRightHanded (mesh.Normals [unityTriangle]));
206+
}
206207

207-
fbxLayer.SetNormals (fbxLayerElement);
208+
fbxLayer.SetNormals (fbxLayerElement);
209+
}
208210
exportedAttribute = true;
209211
}
210212

211-
/// Set the binormals on Layer 0.
212-
using (var fbxLayerElement = FbxLayerElementBinormal.Create (fbxMesh, "Binormals"))
213-
{
214-
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygonVertex);
215-
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eDirect);
213+
/// Set the binormals on Layer 0.
214+
if (mesh.HasValidBinormals(unmergedTriangles.Length)) {
215+
using (var fbxLayerElement = FbxLayerElementBinormal.Create (fbxMesh, "Binormals")) {
216+
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygonVertex);
217+
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eDirect);
216218

217-
// Add one normal per each vertex face index (3 per triangle)
218-
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
219+
// Add one normal per each vertex face index (3 per triangle)
220+
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
219221

220-
for (int n = 0; n < unmergedTriangles.Length; n++) {
221-
int unityTriangle = unmergedTriangles [n];
222-
fbxElementArray.Add (ConvertNormalToRightHanded (mesh.Binormals [unityTriangle]));
222+
for (int n = 0; n < unmergedTriangles.Length; n++) {
223+
int unityTriangle = unmergedTriangles [n];
224+
fbxElementArray.Add (ConvertNormalToRightHanded (mesh.Binormals [unityTriangle]));
225+
}
226+
fbxLayer.SetBinormals (fbxLayerElement);
223227
}
224-
fbxLayer.SetBinormals (fbxLayerElement);
225228
exportedAttribute = true;
226229
}
227230

228231
/// Set the tangents on Layer 0.
229-
using (var fbxLayerElement = FbxLayerElementTangent.Create (fbxMesh, "Tangents"))
230-
{
231-
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygonVertex);
232-
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eDirect);
233-
234-
// Add one normal per each vertex face index (3 per triangle)
235-
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
236-
237-
for (int n = 0; n < unmergedTriangles.Length; n++) {
238-
int unityTriangle = unmergedTriangles [n];
239-
fbxElementArray.Add (ConvertNormalToRightHanded(
240-
new Vector3(
241-
mesh.Tangents[unityTriangle][0],
242-
mesh.Tangents[unityTriangle][1],
243-
mesh.Tangents[unityTriangle][2]
244-
)));
232+
if (mesh.HasValidTangents(unmergedTriangles.Length)) {
233+
using (var fbxLayerElement = FbxLayerElementTangent.Create (fbxMesh, "Tangents")) {
234+
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygonVertex);
235+
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eDirect);
236+
237+
// Add one normal per each vertex face index (3 per triangle)
238+
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
239+
240+
for (int n = 0; n < unmergedTriangles.Length; n++) {
241+
int unityTriangle = unmergedTriangles [n];
242+
fbxElementArray.Add (ConvertNormalToRightHanded (
243+
new Vector3 (
244+
mesh.Tangents [unityTriangle] [0],
245+
mesh.Tangents [unityTriangle] [1],
246+
mesh.Tangents [unityTriangle] [2]
247+
)));
248+
}
249+
fbxLayer.SetTangents (fbxLayerElement);
245250
}
246-
fbxLayer.SetTangents (fbxLayerElement);
247251
exportedAttribute = true;
248252
}
249253

250254
exportedAttribute |= ExportUVs (fbxMesh, mesh, unmergedTriangles);
251255

252-
using (var fbxLayerElement = FbxLayerElementVertexColor.Create (fbxMesh, "VertexColors"))
253-
{
254-
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygonVertex);
255-
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eIndexToDirect);
256-
257-
// set texture coordinates per vertex
258-
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
259-
260-
// (Uni-31596) only copy unique UVs into this array, and index appropriately
261-
for (int n = 0; n < mesh.VertexColors.Length; n++) {
262-
// Converting to Color from Color32, as Color32 stores the colors
263-
// as ints between 0-255, while FbxColor and Color
264-
// use doubles between 0-1
265-
Color color = mesh.VertexColors [n];
266-
fbxElementArray.Add (new FbxColor (color.r,
267-
color.g,
268-
color.b,
269-
color.a));
270-
}
256+
if (mesh.HasValidVertexColors(unmergedTriangles.Length)) {
257+
using (var fbxLayerElement = FbxLayerElementVertexColor.Create (fbxMesh, "VertexColors")) {
258+
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygonVertex);
259+
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eIndexToDirect);
260+
261+
// set texture coordinates per vertex
262+
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetDirectArray ();
271263

272-
// For each face index, point to a texture uv
273-
FbxLayerElementArray fbxIndexArray = fbxLayerElement.GetIndexArray ();
274-
fbxIndexArray.SetCount (unmergedTriangles.Length);
264+
// (Uni-31596) only copy unique UVs into this array, and index appropriately
265+
for (int n = 0; n < mesh.VertexColors.Length; n++) {
266+
// Converting to Color from Color32, as Color32 stores the colors
267+
// as ints between 0-255, while FbxColor and Color
268+
// use doubles between 0-1
269+
Color color = mesh.VertexColors [n];
270+
fbxElementArray.Add (new FbxColor (color.r,
271+
color.g,
272+
color.b,
273+
color.a));
274+
}
275+
276+
// For each face index, point to a texture uv
277+
FbxLayerElementArray fbxIndexArray = fbxLayerElement.GetIndexArray ();
278+
fbxIndexArray.SetCount (unmergedTriangles.Length);
275279

276-
for(int i = 0; i < unmergedTriangles.Length; i++){
277-
fbxIndexArray.SetAt (i, unmergedTriangles [i]);
280+
for (int i = 0; i < unmergedTriangles.Length; i++) {
281+
fbxIndexArray.SetAt (i, unmergedTriangles [i]);
282+
}
283+
fbxLayer.SetVertexColors (fbxLayerElement);
278284
}
279-
fbxLayer.SetVertexColors (fbxLayerElement);
280285
exportedAttribute = true;
281286
}
282287
return exportedAttribute;
@@ -1414,13 +1419,16 @@ public Vector3 [] Binormals {
14141419
var normals = Normals;
14151420
var tangents = Tangents;
14161421

1417-
m_Binormals = new Vector3 [normals.Length];
1422+
if (IsValidArray<Vector3>(normals) &&
1423+
IsValidArray<Vector4>(tangents, normals.Length)
1424+
) {
1425+
m_Binormals = new Vector3 [normals.Length];
14181426

1419-
for (int i = 0; i < normals.Length; i++)
1420-
m_Binormals [i] = Vector3.Cross (normals [i],
1421-
tangents [i])
1427+
for (int i = 0; i < normals.Length; i++)
1428+
m_Binormals [i] = Vector3.Cross (normals [i],
1429+
tangents [i])
14221430
* tangents [i].w;
1423-
1431+
}
14241432
}
14251433
return m_Binormals;
14261434
}
@@ -1493,6 +1501,36 @@ public MeshInfo (Mesh mesh, Material[] materials)
14931501
}
14941502
}
14951503
}
1504+
1505+
/// <summary>
1506+
/// Determines whether this instance is a valid array with the specified length.
1507+
/// </summary>
1508+
/// <returns><c>true</c> if this instance is valid array; otherwise, <c>false</c>.</returns>
1509+
/// <param name="array">Array.</param>
1510+
/// <param name="expectedLength">Expected length.</param>
1511+
/// <typeparam name="T">The 1st type parameter.</typeparam>
1512+
public static bool IsValidArray<T>(T[] array, int expectedLength = -1)
1513+
{
1514+
return array != null &&
1515+
array.Length > 0 &&
1516+
(expectedLength >= 0 ? array.Length == expectedLength : true);
1517+
}
1518+
1519+
public bool HasValidNormals(int expectedLength){
1520+
return IsValidArray<Vector3> (Normals, expectedLength);
1521+
}
1522+
1523+
public bool HasValidBinormals(int expectedLength){
1524+
return IsValidArray<Vector3> (Binormals, expectedLength);
1525+
}
1526+
1527+
public bool HasValidTangents(int expectedLength){
1528+
return IsValidArray<Vector4> (Tangents, expectedLength);
1529+
}
1530+
1531+
public bool HasValidVertexColors(int expectedLength){
1532+
return IsValidArray<Color32> (VertexColors, expectedLength);
1533+
}
14961534
}
14971535

14981536
/// <summary>

0 commit comments

Comments
 (0)