Skip to content

Commit faa6859

Browse files
authored
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
2 parents ba90d0c + d05447c commit faa6859

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
}
@@ -1219,7 +1236,7 @@ internal bool ExportTransform (UnityEngine.Transform unityTransform, FbxNode fbx
12191236
/// if this game object is a model prefab then export with shared components
12201237
/// </summary>
12211238
[SecurityPermission(SecurityAction.LinkDemand)]
1222-
private bool ExportInstance(GameObject unityGo, FbxNode fbxNode)
1239+
private bool ExportInstance(GameObject unityGo, FbxScene fbxScene, FbxNode fbxNode)
12231240
{
12241241
if (!unityGo || fbxNode == null)
12251242
{
@@ -1242,10 +1259,10 @@ private bool ExportInstance(GameObject unityGo, FbxNode fbxNode)
12421259

12431260
FbxMesh fbxMesh = null;
12441261

1245-
if (!SharedMeshes.TryGetValue (unityPrefabParent.name, out fbxMesh))
1262+
if (!SharedMeshes.TryGetValue (unityPrefabParent.GetInstanceID(), out fbxMesh))
12461263
{
12471264
if (ExportMesh (unityGo, fbxNode) && fbxNode.GetMesh() != null) {
1248-
SharedMeshes [unityPrefabParent.name] = fbxNode.GetMesh ();
1265+
SharedMeshes [unityPrefabParent.GetInstanceID()] = fbxNode.GetMesh ();
12491266
return true;
12501267
}
12511268
return false;
@@ -1259,10 +1276,15 @@ private bool ExportInstance(GameObject unityGo, FbxNode fbxNode)
12591276
if (materials != null)
12601277
{
12611278
foreach (var mat in materials) {
1262-
if (MaterialMap.TryGetValue(mat.name, out newMaterial))
1279+
if (MaterialMap.TryGetValue(mat.GetInstanceID(), out newMaterial))
12631280
{
12641281
fbxNode.AddMaterial(newMaterial);
12651282
}
1283+
else
1284+
{
1285+
// create new material
1286+
ExportMaterial(mat, fbxScene, fbxNode);
1287+
}
12661288
}
12671289
}
12681290

@@ -2515,18 +2537,59 @@ private void SetDefaultCamera (FbxScene fbxScene)
25152537
/// </summary>
25162538
/// <returns>Unique name</returns>
25172539
/// <param name="name">Name</param>
2518-
private string GetUniqueName(string name)
2540+
/// <param name="nameToCountMap">The dictionary to use to map name to # of occurences</param>
2541+
private string GetUniqueName(string name, Dictionary<string, int> nameToCountMap)
25192542
{
25202543
var uniqueName = name;
2521-
if (NameToIndexMap.ContainsKey (name)) {
2522-
uniqueName = string.Format (UniqueNameFormat, name, NameToIndexMap [name]);
2523-
NameToIndexMap [name]++;
2524-
} else {
2525-
NameToIndexMap [name] = 1;
2544+
int count;
2545+
if (nameToCountMap.TryGetValue(name, out count))
2546+
{
2547+
uniqueName = string.Format(UniqueNameFormat, name, count);
2548+
}
2549+
else
2550+
{
2551+
count = 0;
25262552
}
2553+
nameToCountMap[name] = count + 1;
25272554
return uniqueName;
25282555
}
25292556

2557+
/// <summary>
2558+
/// Ensures that the inputted name is unique.
2559+
/// If a duplicate name is found, then it is incremented.
2560+
/// e.g. Sphere becomes Sphere_1
2561+
/// </summary>
2562+
/// <returns>Unique name</returns>
2563+
/// <param name="name">Name</param>
2564+
private string GetUniqueFbxNodeName(string name)
2565+
{
2566+
return GetUniqueName(name, NameToIndexMap);
2567+
}
2568+
2569+
/// <summary>
2570+
/// Ensures that the inputted material name is unique.
2571+
/// If a duplicate name is found, then it is incremented.
2572+
/// e.g. mat becomes mat_1
2573+
/// </summary>
2574+
/// <param name="name">Name</param>
2575+
/// <returns>Unique material name</returns>
2576+
private string GetUniqueMaterialName(string name)
2577+
{
2578+
return GetUniqueName(name, MaterialNameToIndexMap);
2579+
}
2580+
2581+
/// <summary>
2582+
/// Ensures that the inputted texture name is unique.
2583+
/// If a duplicate name is found, then it is incremented.
2584+
/// e.g. tex becomes tex_1
2585+
/// </summary>
2586+
/// <param name="name">Name</param>
2587+
/// <returns>Unique texture name</returns>
2588+
private string GetUniqueTextureName(string name)
2589+
{
2590+
return GetUniqueName(name, TextureNameToIndexMap);
2591+
}
2592+
25302593
/// <summary>
25312594
/// Create a fbxNode from unityGo.
25322595
/// </summary>
@@ -2546,7 +2609,7 @@ private FbxNode CreateFbxNode(GameObject unityGo, FbxScene fbxScene)
25462609
}
25472610
}
25482611

2549-
FbxNode fbxNode = FbxNode.Create(fbxScene, GetUniqueName(fbxName));
2612+
FbxNode fbxNode = FbxNode.Create(fbxScene, GetUniqueFbxNodeName(fbxName));
25502613

25512614
// Default inheritance type in FBX is RrSs, which causes scaling issues in Maya as
25522615
// both Maya and Unity use RSrs inheritance by default.
@@ -3126,7 +3189,7 @@ private bool ExportComponents(FbxScene fbxScene)
31263189
var fbxNode = entry.Value;
31273190

31283191
// try export mesh
3129-
bool exportedMesh = ExportInstance (unityGo, fbxNode);
3192+
bool exportedMesh = ExportInstance (unityGo, fbxScene, fbxNode);
31303193

31313194
if (!exportedMesh) {
31323195
exportedMesh = ExportMesh (unityGo, fbxNode);

0 commit comments

Comments
 (0)