Skip to content

Commit 5ad3998

Browse files
authored
Merge pull request #35 from Unity-Technologies/UNI-20812-export-multiple-materials-per-mesh
Uni 20812 export multiple materials per mesh
2 parents c12c282 + 139350e commit 5ad3998

File tree

1 file changed

+46
-16
lines changed

1 file changed

+46
-16
lines changed

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,13 @@ public FbxDouble3 GetMaterialColor (Material unityMaterial, string unityPropName
264264
/// <summary>
265265
/// Export (and map) a Unity PBS material to FBX classic material
266266
/// </summary>
267-
public FbxSurfaceMaterial ExportMaterial (Material unityMaterial, FbxScene fbxScene, FbxMesh fbxMesh)
267+
public FbxSurfaceMaterial ExportMaterial (Material unityMaterial, FbxScene fbxScene)
268268
{
269269
if (Verbose)
270270
Debug.Log (string.Format ("exporting material {0}", unityMaterial.name));
271271

272272
var materialName = unityMaterial ? unityMaterial.name : "DefaultMaterial";
273273
if (MaterialMap.ContainsKey (materialName)) {
274-
AssignLayerElementMaterial (fbxMesh);
275274
return MaterialMap [materialName];
276275
}
277276

@@ -303,13 +302,21 @@ public FbxSurfaceMaterial ExportMaterial (Material unityMaterial, FbxScene fbxSc
303302
ExportTexture (unityMaterial, "_SpecGlosMap", fbxMaterial, FbxSurfaceMaterial.sSpecular);
304303
}
305304

306-
AssignLayerElementMaterial (fbxMesh);
307-
308305
MaterialMap.Add (materialName, fbxMaterial);
309306
return fbxMaterial;
310307
}
311308

312-
private void AssignLayerElementMaterial(FbxMesh fbxMesh)
309+
/// <summary>
310+
/// Sets up the material to polygon mapping for fbxMesh.
311+
/// To determine which part of the mesh uses which material, look at the submeshes
312+
/// and which polygons they represent.
313+
/// Assuming equal number of materials as submeshes, and that they are in the same order.
314+
/// (i.e. submesh 1 uses material 1)
315+
/// </summary>
316+
/// <param name="fbxMesh">Fbx mesh.</param>
317+
/// <param name="mesh">Mesh.</param>
318+
/// <param name="materials">Materials.</param>
319+
private void AssignLayerElementMaterial(FbxMesh fbxMesh, Mesh mesh, int materialCount)
313320
{
314321
// Add FbxLayerElementMaterial to layer 0 of the node
315322
FbxLayer fbxLayer = fbxMesh.GetLayer (0 /* default layer */);
@@ -319,14 +326,31 @@ private void AssignLayerElementMaterial(FbxMesh fbxMesh)
319326
}
320327

321328
using (var fbxLayerElement = FbxLayerElementMaterial.Create (fbxMesh, "Material")) {
322-
// Using all same means that the entire mesh uses the same material
323-
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eAllSame);
324-
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eIndexToDirect);
329+
// if there is only one material then set everything to that material
330+
if (materialCount == 1) {
331+
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eAllSame);
332+
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eIndexToDirect);
333+
334+
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetIndexArray ();
335+
fbxElementArray.Add (0);
336+
} else {
337+
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygon);
338+
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eIndexToDirect);
339+
340+
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetIndexArray ();
325341

326-
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetIndexArray ();
342+
// assuming that each polygon is a triangle
343+
// TODO: Add support for other mesh topologies (e.g. quads)
344+
fbxElementArray.SetCount (mesh.triangles.Length / 3);
327345

328-
// Map the entire geometry to the FbxNode material at index 0
329-
fbxElementArray.Add (0);
346+
for (int i = 0; i < mesh.subMeshCount; i++) {
347+
int start = ((int)mesh.GetIndexStart (i)) / 3;
348+
int count = ((int)mesh.GetIndexCount (i)) / 3;
349+
for (int j = start; j < start + count; j++) {
350+
fbxElementArray.SetAt (j, i);
351+
}
352+
}
353+
}
330354
fbxLayer.SetMaterials (fbxLayerElement);
331355
}
332356
}
@@ -387,8 +411,10 @@ meshInfo.Vertices [v].z*UnitScaleFactor
387411
}
388412
}
389413

390-
var fbxMaterial = ExportMaterial (meshInfo.Material, fbxScene, fbxMesh);
391-
fbxNode.AddMaterial (fbxMaterial);
414+
foreach (var mat in meshInfo.Materials) {
415+
var fbxMaterial = ExportMaterial (mat, fbxScene);
416+
fbxNode.AddMaterial (fbxMaterial);
417+
}
392418

393419
/*
394420
* Triangles have to be added in reverse order,
@@ -419,6 +445,8 @@ meshInfo.Vertices [v].z*UnitScaleFactor
419445
fbxMesh.EndPolygon ();
420446
}
421447

448+
AssignLayerElementMaterial (fbxMesh, meshInfo.mesh, meshInfo.Materials.Length);
449+
422450
ExportComponentAttributes (meshInfo, fbxMesh, unmergedTriangles);
423451

424452
// set the fbxNode containing the mesh
@@ -855,7 +883,7 @@ public Vector3 [] Binormals {
855883
/// The material used, if any; otherwise null.
856884
/// We don't support multiple materials on one gameobject.
857885
/// </summary>
858-
public Material Material {
886+
public Material[] Materials {
859887
get {
860888
if (!unityObject) {
861889
return null;
@@ -866,12 +894,14 @@ public Material Material {
866894
}
867895

868896
if (FbxExporters.EditorTools.ExportSettings.instance.mayaCompatibleNames) {
869-
renderer.sharedMaterial.name = ConvertToMayaCompatibleName (renderer.sharedMaterial.name);
897+
foreach (var mat in renderer.sharedMaterials) {
898+
mat.name = ConvertToMayaCompatibleName (mat.name);
899+
}
870900
}
871901

872902
// .material instantiates a new material, which is bad
873903
// most of the time.
874-
return renderer.sharedMaterial;
904+
return renderer.sharedMaterials;
875905
}
876906
}
877907

0 commit comments

Comments
 (0)