Skip to content

Commit b5b9e2b

Browse files
committed
Merge pull request #514 from Unity-Technologies/UT-3382-fix-export-issue-with-identical-mesh-and-material-names
UT-3382 map by ID instead of name for materials and meshes (cherry picked from commit faa6859)
1 parent 76a3690 commit b5b9e2b

File tree

1 file changed

+84
-21
lines changed

1 file changed

+84
-21
lines changed

com.unity.formats.fbx/Editor/FbxExporter.cs

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -165,26 +165,38 @@ internal enum FbxNodeRelationType
165165
Dictionary<FbxNode, Dictionary<FbxConstraint, System.Type>> MapConstrainedObjectToConstraints = new Dictionary<FbxNode, Dictionary<FbxConstraint, System.Type>>();
166166

167167
/// <summary>
168-
/// Map Unity material name to FBX material object
168+
/// Map Unity material ID to FBX material object
169169
/// </summary>
170-
Dictionary<string, FbxSurfaceMaterial> MaterialMap = new Dictionary<string, FbxSurfaceMaterial> ();
170+
Dictionary<int, FbxSurfaceMaterial> MaterialMap = new Dictionary<int, FbxSurfaceMaterial> ();
171171

172172
/// <summary>
173173
/// Map texture filename name to FBX texture object
174174
/// </summary>
175175
Dictionary<string, FbxTexture> TextureMap = new Dictionary<string, FbxTexture> ();
176176

177177
/// <summary>
178-
/// Map the name of a prefab to an FbxMesh (for preserving instances)
178+
/// Map the ID of a prefab to an FbxMesh (for preserving instances)
179179
/// </summary>
180-
Dictionary<string, FbxMesh> SharedMeshes = new Dictionary<string, FbxMesh> ();
180+
Dictionary<int, FbxMesh> SharedMeshes = new Dictionary<int, FbxMesh> ();
181181

182182
/// <summary>
183183
/// Map for the Name of an Object to number of objects with this name.
184184
/// Used for enforcing unique names on export.
185185
/// </summary>
186186
Dictionary<string, int> NameToIndexMap = new Dictionary<string, int> ();
187187

188+
/// <summary>
189+
/// Map for the Material Name to number of materials with this name.
190+
/// Used for enforcing unique names on export.
191+
/// </summary>
192+
Dictionary<string, int> MaterialNameToIndexMap = new Dictionary<string, int>();
193+
194+
/// <summary>
195+
/// Map for the Texture Name to number of textures with this name.
196+
/// Used for enforcing unique names on export.
197+
/// </summary>
198+
Dictionary<string, int> TextureNameToIndexMap = new Dictionary<string, int>();
199+
188200
/// <summary>
189201
/// Format for creating unique names
190202
/// </summary>
@@ -620,7 +632,8 @@ internal bool ExportTexture (Material unityMaterial, string unityPropName,
620632

621633
// Find or create an fbx texture and link it up to the fbx material.
622634
if (!TextureMap.ContainsKey (textureSourceFullPath)) {
623-
var fbxTexture = FbxFileTexture.Create (fbxMaterial, fbxPropName + "_Texture");
635+
var textureName = GetUniqueTextureName(fbxPropName + "_Texture");
636+
var fbxTexture = FbxFileTexture.Create (fbxMaterial, textureName);
624637
fbxTexture.SetFileName (textureSourceFullPath);
625638
fbxTexture.SetTextureUse (FbxTexture.ETextureUse.eStandard);
626639
fbxTexture.SetMappingType (FbxTexture.EMappingType.eUV);
@@ -655,15 +668,19 @@ internal bool ExportMaterial (Material unityMaterial, FbxScene fbxScene, FbxNode
655668
unityMaterial = DefaultMaterial;
656669
}
657670

658-
var unityName = unityMaterial.name;
659-
if (MaterialMap.ContainsKey (unityName)) {
660-
fbxNode.AddMaterial (MaterialMap [unityName]);
671+
var unityID = unityMaterial.GetInstanceID();
672+
FbxSurfaceMaterial mappedMaterial;
673+
if (MaterialMap.TryGetValue (unityID, out mappedMaterial)) {
674+
fbxNode.AddMaterial (mappedMaterial);
661675
return true;
662676
}
663677

678+
var unityName = unityMaterial.name;
664679
var fbxName = ExportOptions.UseMayaCompatibleNames
665680
? ConvertToMayaCompatibleName(unityName) : unityName;
666681

682+
fbxName = GetUniqueMaterialName(fbxName);
683+
667684
if (Verbose) {
668685
if (unityName != fbxName) {
669686
Debug.Log (string.Format ("exporting material {0} as {1}", unityName, fbxName));
@@ -700,7 +717,7 @@ internal bool ExportMaterial (Material unityMaterial, FbxScene fbxScene, FbxNode
700717
ExportTexture (unityMaterial, "_SpecGlosMap", fbxMaterial, FbxSurfaceMaterial.sSpecular);
701718
}
702719

703-
MaterialMap.Add (unityName, fbxMaterial);
720+
MaterialMap.Add (unityID, fbxMaterial);
704721
fbxNode.AddMaterial (fbxMaterial);
705722
return true;
706723
}
@@ -1274,7 +1291,7 @@ internal bool ExportTransform (UnityEngine.Transform unityTransform, FbxNode fbx
12741291
/// if this game object is a model prefab then export with shared components
12751292
/// </summary>
12761293
[SecurityPermission(SecurityAction.LinkDemand)]
1277-
private bool ExportInstance(GameObject unityGo, FbxNode fbxNode)
1294+
private bool ExportInstance(GameObject unityGo, FbxScene fbxScene, FbxNode fbxNode)
12781295
{
12791296
if (!unityGo || fbxNode == null)
12801297
{
@@ -1297,10 +1314,10 @@ private bool ExportInstance(GameObject unityGo, FbxNode fbxNode)
12971314

12981315
FbxMesh fbxMesh = null;
12991316

1300-
if (!SharedMeshes.TryGetValue (unityPrefabParent.name, out fbxMesh))
1317+
if (!SharedMeshes.TryGetValue (unityPrefabParent.GetInstanceID(), out fbxMesh))
13011318
{
13021319
if (ExportMesh (unityGo, fbxNode) && fbxNode.GetMesh() != null) {
1303-
SharedMeshes [unityPrefabParent.name] = fbxNode.GetMesh ();
1320+
SharedMeshes [unityPrefabParent.GetInstanceID()] = fbxNode.GetMesh ();
13041321
return true;
13051322
}
13061323
return false;
@@ -1314,10 +1331,15 @@ private bool ExportInstance(GameObject unityGo, FbxNode fbxNode)
13141331
if (materials != null)
13151332
{
13161333
foreach (var mat in materials) {
1317-
if (MaterialMap.TryGetValue(mat.name, out newMaterial))
1334+
if (MaterialMap.TryGetValue(mat.GetInstanceID(), out newMaterial))
13181335
{
13191336
fbxNode.AddMaterial(newMaterial);
13201337
}
1338+
else
1339+
{
1340+
// create new material
1341+
ExportMaterial(mat, fbxScene, fbxNode);
1342+
}
13211343
}
13221344
}
13231345

@@ -2564,18 +2586,59 @@ private void SetDefaultCamera (FbxScene fbxScene)
25642586
/// </summary>
25652587
/// <returns>Unique name</returns>
25662588
/// <param name="name">Name</param>
2567-
private string GetUniqueName(string name)
2589+
/// <param name="nameToCountMap">The dictionary to use to map name to # of occurences</param>
2590+
private string GetUniqueName(string name, Dictionary<string, int> nameToCountMap)
25682591
{
25692592
var uniqueName = name;
2570-
if (NameToIndexMap.ContainsKey (name)) {
2571-
uniqueName = string.Format (UniqueNameFormat, name, NameToIndexMap [name]);
2572-
NameToIndexMap [name]++;
2573-
} else {
2574-
NameToIndexMap [name] = 1;
2593+
int count;
2594+
if (nameToCountMap.TryGetValue(name, out count))
2595+
{
2596+
uniqueName = string.Format(UniqueNameFormat, name, count);
2597+
}
2598+
else
2599+
{
2600+
count = 0;
25752601
}
2602+
nameToCountMap[name] = count + 1;
25762603
return uniqueName;
25772604
}
25782605

2606+
/// <summary>
2607+
/// Ensures that the inputted name is unique.
2608+
/// If a duplicate name is found, then it is incremented.
2609+
/// e.g. Sphere becomes Sphere_1
2610+
/// </summary>
2611+
/// <returns>Unique name</returns>
2612+
/// <param name="name">Name</param>
2613+
private string GetUniqueFbxNodeName(string name)
2614+
{
2615+
return GetUniqueName(name, NameToIndexMap);
2616+
}
2617+
2618+
/// <summary>
2619+
/// Ensures that the inputted material name is unique.
2620+
/// If a duplicate name is found, then it is incremented.
2621+
/// e.g. mat becomes mat_1
2622+
/// </summary>
2623+
/// <param name="name">Name</param>
2624+
/// <returns>Unique material name</returns>
2625+
private string GetUniqueMaterialName(string name)
2626+
{
2627+
return GetUniqueName(name, MaterialNameToIndexMap);
2628+
}
2629+
2630+
/// <summary>
2631+
/// Ensures that the inputted texture name is unique.
2632+
/// If a duplicate name is found, then it is incremented.
2633+
/// e.g. tex becomes tex_1
2634+
/// </summary>
2635+
/// <param name="name">Name</param>
2636+
/// <returns>Unique texture name</returns>
2637+
private string GetUniqueTextureName(string name)
2638+
{
2639+
return GetUniqueName(name, TextureNameToIndexMap);
2640+
}
2641+
25792642
/// <summary>
25802643
/// Create a fbxNode from unityGo.
25812644
/// </summary>
@@ -2595,7 +2658,7 @@ private FbxNode CreateFbxNode(GameObject unityGo, FbxScene fbxScene)
25952658
}
25962659
}
25972660

2598-
FbxNode fbxNode = FbxNode.Create(fbxScene, GetUniqueName(fbxName));
2661+
FbxNode fbxNode = FbxNode.Create(fbxScene, GetUniqueFbxNodeName(fbxName));
25992662

26002663
// Default inheritance type in FBX is RrSs, which causes scaling issues in Maya as
26012664
// both Maya and Unity use RSrs inheritance by default.
@@ -3171,7 +3234,7 @@ private bool ExportComponents(FbxScene fbxScene)
31713234
var fbxNode = entry.Value;
31723235

31733236
// try export mesh
3174-
bool exportedMesh = ExportInstance (unityGo, fbxNode);
3237+
bool exportedMesh = ExportInstance (unityGo, fbxScene, fbxNode);
31753238

31763239
if (!exportedMesh) {
31773240
exportedMesh = ExportMesh (unityGo, fbxNode);

0 commit comments

Comments
 (0)