Skip to content

Commit f5ad3aa

Browse files
committed
Merge remote-tracking branch 'refs/remotes/origin/master' into UNI-20956-export-lightmap-uvs
# Conflicts: # Assets/FbxExporters/Editor/FbxExporter.cs
2 parents fad7a88 + c51ec5e commit f5ad3aa

File tree

2 files changed

+377
-20
lines changed

2 files changed

+377
-20
lines changed

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 91 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ public static ModelExporter Create ()
6565
Dictionary<string, FbxTexture> TextureMap = new Dictionary<string, FbxTexture> ();
6666

6767
/// <summary>
68+
/// Map the name of a prefab to an FbxMesh (for preserving instances)
6869
/// </summary>
70+
Dictionary<string, FbxMesh> SharedMeshes = new Dictionary<string, FbxMesh>();
6971

7072
/// <summary>
7173
/// return layer for mesh
@@ -304,14 +306,13 @@ public FbxDouble3 GetMaterialColor (Material unityMaterial, string unityPropName
304306
/// <summary>
305307
/// Export (and map) a Unity PBS material to FBX classic material
306308
/// </summary>
307-
public FbxSurfaceMaterial ExportMaterial (Material unityMaterial, FbxScene fbxScene, FbxMesh fbxMesh)
309+
public FbxSurfaceMaterial ExportMaterial (Material unityMaterial, FbxScene fbxScene)
308310
{
309311
if (Verbose)
310312
Debug.Log (string.Format ("exporting material {0}", unityMaterial.name));
311313

312314
var materialName = unityMaterial ? unityMaterial.name : "DefaultMaterial";
313315
if (MaterialMap.ContainsKey (materialName)) {
314-
AssignLayerElementMaterial (fbxMesh);
315316
return MaterialMap [materialName];
316317
}
317318

@@ -343,13 +344,21 @@ public FbxSurfaceMaterial ExportMaterial (Material unityMaterial, FbxScene fbxSc
343344
ExportTexture (unityMaterial, "_SpecGlosMap", fbxMaterial, FbxSurfaceMaterial.sSpecular);
344345
}
345346

346-
AssignLayerElementMaterial (fbxMesh);
347-
348347
MaterialMap.Add (materialName, fbxMaterial);
349348
return fbxMaterial;
350349
}
351350

352-
private void AssignLayerElementMaterial(FbxMesh fbxMesh)
351+
/// <summary>
352+
/// Sets up the material to polygon mapping for fbxMesh.
353+
/// To determine which part of the mesh uses which material, look at the submeshes
354+
/// and which polygons they represent.
355+
/// Assuming equal number of materials as submeshes, and that they are in the same order.
356+
/// (i.e. submesh 1 uses material 1)
357+
/// </summary>
358+
/// <param name="fbxMesh">Fbx mesh.</param>
359+
/// <param name="mesh">Mesh.</param>
360+
/// <param name="materials">Materials.</param>
361+
private void AssignLayerElementMaterial(FbxMesh fbxMesh, Mesh mesh, int materialCount)
353362
{
354363
// Add FbxLayerElementMaterial to layer 0 of the node
355364
FbxLayer fbxLayer = fbxMesh.GetLayer (0 /* default layer */);
@@ -359,14 +368,31 @@ private void AssignLayerElementMaterial(FbxMesh fbxMesh)
359368
}
360369

361370
using (var fbxLayerElement = FbxLayerElementMaterial.Create (fbxMesh, "Material")) {
362-
// Using all same means that the entire mesh uses the same material
363-
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eAllSame);
364-
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eIndexToDirect);
371+
// if there is only one material then set everything to that material
372+
if (materialCount == 1) {
373+
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eAllSame);
374+
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eIndexToDirect);
375+
376+
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetIndexArray ();
377+
fbxElementArray.Add (0);
378+
} else {
379+
fbxLayerElement.SetMappingMode (FbxLayerElement.EMappingMode.eByPolygon);
380+
fbxLayerElement.SetReferenceMode (FbxLayerElement.EReferenceMode.eIndexToDirect);
381+
382+
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetIndexArray ();
365383

366-
FbxLayerElementArray fbxElementArray = fbxLayerElement.GetIndexArray ();
384+
// assuming that each polygon is a triangle
385+
// TODO: Add support for other mesh topologies (e.g. quads)
386+
fbxElementArray.SetCount (mesh.triangles.Length / 3);
367387

368-
// Map the entire geometry to the FbxNode material at index 0
369-
fbxElementArray.Add (0);
388+
for (int i = 0; i < mesh.subMeshCount; i++) {
389+
int start = ((int)mesh.GetIndexStart (i)) / 3;
390+
int count = ((int)mesh.GetIndexCount (i)) / 3;
391+
for (int j = start; j < start + count; j++) {
392+
fbxElementArray.SetAt (j, i);
393+
}
394+
}
395+
}
370396
fbxLayer.SetMaterials (fbxLayerElement);
371397
}
372398
}
@@ -375,10 +401,10 @@ private void AssignLayerElementMaterial(FbxMesh fbxMesh)
375401
/// Unconditionally export this mesh object to the file.
376402
/// We have decided; this mesh is definitely getting exported.
377403
/// </summary>
378-
public void ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene, bool weldVertices = true)
404+
public FbxMesh ExportMesh (MeshInfo meshInfo, FbxNode fbxNode, FbxScene fbxScene, bool weldVertices = true)
379405
{
380406
if (!meshInfo.IsValid)
381-
return;
407+
return null;
382408

383409
NumMeshes++;
384410
NumTriangles += meshInfo.Triangles.Length / 3;
@@ -427,8 +453,10 @@ meshInfo.Vertices [v].z*UnitScaleFactor
427453
}
428454
}
429455

430-
var fbxMaterial = ExportMaterial (meshInfo.Material, fbxScene, fbxMesh);
431-
fbxNode.AddMaterial (fbxMaterial);
456+
foreach (var mat in meshInfo.Materials) {
457+
var fbxMaterial = ExportMaterial (mat, fbxScene);
458+
fbxNode.AddMaterial (fbxMaterial);
459+
}
432460

433461
/*
434462
* Triangles have to be added in reverse order,
@@ -459,11 +487,15 @@ meshInfo.Vertices [v].z*UnitScaleFactor
459487
fbxMesh.EndPolygon ();
460488
}
461489

490+
AssignLayerElementMaterial (fbxMesh, meshInfo.mesh, meshInfo.Materials.Length);
491+
462492
ExportComponentAttributes (meshInfo, fbxMesh, unmergedTriangles);
463493

464494
// set the fbxNode containing the mesh
465495
fbxNode.SetNodeAttribute (fbxMesh);
466496
fbxNode.SetShadingMode (FbxNode.EShadingMode.eWireFrame);
497+
498+
return fbxMesh;
467499
}
468500

469501
// get a fbxNode's global default position.
@@ -517,6 +549,40 @@ protected void ExportTransform (UnityEngine.Transform unityTransform, FbxNode fb
517549
return;
518550
}
519551

552+
/// <summary>
553+
/// if this game object is a model prefab then export with shared components
554+
/// </summary>
555+
protected bool ExportInstance (GameObject unityGo, FbxNode fbxNode, FbxScene fbxScene)
556+
{
557+
PrefabType unityPrefabType = PrefabUtility.GetPrefabType(unityGo);
558+
559+
if (unityPrefabType != PrefabType.PrefabInstance) return false;
560+
561+
Object unityPrefabParent = PrefabUtility.GetPrefabParent (unityGo);
562+
563+
if (Verbose)
564+
Debug.Log (string.Format ("exporting instance {0}({1})", unityGo.name, unityPrefabParent.name));
565+
566+
FbxMesh fbxMesh = null;
567+
568+
if (!SharedMeshes.TryGetValue (unityPrefabParent.name, out fbxMesh))
569+
{
570+
bool weldVertices = FbxExporters.EditorTools.ExportSettings.instance.weldVertices;
571+
fbxMesh = ExportMesh (GetMeshInfo (unityGo), fbxNode, fbxScene, weldVertices);
572+
if (fbxMesh != null) {
573+
SharedMeshes [unityPrefabParent.name] = fbxMesh;
574+
}
575+
}
576+
577+
if (fbxMesh == null) return false;
578+
579+
// set the fbxNode containing the mesh
580+
fbxNode.SetNodeAttribute (fbxMesh);
581+
fbxNode.SetShadingMode (FbxNode.EShadingMode.eWireFrame);
582+
583+
return true;
584+
}
585+
520586
/// <summary>
521587
/// Unconditionally export components on this game object
522588
/// </summary>
@@ -545,8 +611,11 @@ protected int ExportComponents (
545611

546612
ExportTransform ( unityGo.transform, fbxNode, exportType);
547613

548-
bool weldVertices = FbxExporters.EditorTools.ExportSettings.instance.weldVertices;
549-
ExportMesh (GetMeshInfo( unityGo ), fbxNode, fbxScene, weldVertices);
614+
// try exporting mesh as an instance, export regularly if we cannot
615+
if (!ExportInstance (unityGo, fbxNode, fbxScene)) {
616+
bool weldVertices = FbxExporters.EditorTools.ExportSettings.instance.weldVertices;
617+
ExportMesh (GetMeshInfo (unityGo), fbxNode, fbxScene, weldVertices);
618+
}
550619

551620
if (Verbose)
552621
Debug.Log (string.Format ("exporting {0}", fbxNode.GetName ()));
@@ -895,7 +964,7 @@ public Vector3 [] Binormals {
895964
/// The material used, if any; otherwise null.
896965
/// We don't support multiple materials on one gameobject.
897966
/// </summary>
898-
public Material Material {
967+
public Material[] Materials {
899968
get {
900969
if (!unityObject) {
901970
return null;
@@ -906,12 +975,14 @@ public Material Material {
906975
}
907976

908977
if (FbxExporters.EditorTools.ExportSettings.instance.mayaCompatibleNames) {
909-
renderer.sharedMaterial.name = ConvertToMayaCompatibleName (renderer.sharedMaterial.name);
978+
foreach (var mat in renderer.sharedMaterials) {
979+
mat.name = ConvertToMayaCompatibleName (mat.name);
980+
}
910981
}
911982

912983
// .material instantiates a new material, which is bad
913984
// most of the time.
914-
return renderer.sharedMaterial;
985+
return renderer.sharedMaterials;
915986
}
916987
}
917988

0 commit comments

Comments
 (0)