Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generate unique names for nodes in 3d models #795

Prev Previous commit
Next Next commit
Simplify unique node name generation logic
This commit improves developer experience as the original node name is kept visible, and the UID is appended to the end

[CI BUILD DEV] [CI BUILD]
eeropomell committed Dec 8, 2024
commit ea48923d894ceba71310b999c98fc0a3cf62a014
61 changes: 21 additions & 40 deletions Assets/Scripts/Model.cs
Original file line number Diff line number Diff line change
@@ -248,18 +248,8 @@ public IExportableMaterial GetExportableMaterial(Material material)
EnsureCollectorExists();
return m_ImportMaterialCollector.GetExportableMaterial(material);
}


public struct UidToNodeMapItem
{
public Transform nodeTransform;
public string nodeRealName;
}

// initialized when model is loaded
// - initialization uses GetInstanceID() to get unique id for each node in the model
// - this dictionary is currently used for finding subtrees when breaking models apart, in ModelWidget.cs
// - unique identifiers for nodes are needed because node names in e.g., glTF aren't unique
public Dictionary<int, UidToNodeMapItem> UidToNodeMap;

public Model(Location location)
{
@@ -854,8 +844,6 @@ private void CalcBoundsNonGltf(GameObject go)

}

static ProfilerMarker _endCreatePrefabPerfMarker = new ProfilerMarker("Model.EndCreatePrefab");

public void EndCreatePrefab(GameObject go, List<string> warnings)
{

@@ -875,53 +863,46 @@ public void EndCreatePrefab(GameObject go, List<string> warnings)
}
m_ModelParent = go.transform;

_endCreatePrefabPerfMarker.Begin();

InitializeUidToNodeMap(m_ModelParent);
#if DEVELOPMENT_BUILD || UNITY_EDITOR
ProfilerMarker generateUniqueNamesPerfMarker = new ProfilerMarker("Model.GenerateUniqueNames");
generateUniqueNamesPerfMarker.Begin();
#endif

GenerateUniqueNames(m_ModelParent);

_endCreatePrefabPerfMarker.End();
#if DEVELOPMENT_BUILD || UNITY_EDITOR
generateUniqueNamesPerfMarker.End();
#endif

// !!! Add to material dictionary here?

m_Valid = true;
DisplayWarnings(warnings);

}



public string GetNodeRealNameFromID(int uid)
{
if (UidToNodeMap.ContainsKey(uid))
{
return UidToNodeMap[uid].nodeRealName;
}
return null;
}


private void InitializeUidToNodeMap(Transform rootNode)
// This method is called when the model has been loaded and the node tree is available
// This method is necessary because (1) nodes in e.g glTF files don't need to have unique names
// and (2) there's code in at least ModelWidget that searches for specific nodes using node names
private static void GenerateUniqueNames(Transform rootNode)
{
// the immediate children of rootNode are the root nodes of the model

UidToNodeMap = new Dictionary<int, UidToNodeMapItem>();

void ProcessNode(Transform node)
void SetUniqueNameForNode(Transform node)
{
UidToNodeMapItem uidToNodeMapItem = new UidToNodeMapItem();
uidToNodeMapItem.nodeTransform = node;
uidToNodeMapItem.nodeRealName = node.name;
node.name = node.gameObject.GetInstanceID().ToString();
UidToNodeMap[node.gameObject.GetInstanceID()] = uidToNodeMapItem;

// GetInstanceID returns a unique ID for every GameObject during a runtime session
node.name += " uid: " + node.gameObject.GetInstanceID();

foreach (Transform child in node)
{
ProcessNode(child);
SetUniqueNameForNode(child);
}
}

foreach (Transform child in rootNode)
{
ProcessNode(child);
SetUniqueNameForNode(child);
}
}