private BabylonNode exportNodeRec(IIGameNode maxGameNode, BabylonScene babylonScene, IIGameScene maxGameScene) { BabylonNode babylonNode = null; switch (maxGameNode.IGameObject.IGameType) { case Autodesk.Max.IGameObject.ObjectTypes.Mesh: babylonNode = ExportMesh(maxGameScene, maxGameNode, babylonScene); break; case Autodesk.Max.IGameObject.ObjectTypes.Camera: babylonNode = ExportCamera(maxGameScene, maxGameNode, babylonScene); break; case Autodesk.Max.IGameObject.ObjectTypes.Light: babylonNode = ExportLight(maxGameScene, maxGameNode, babylonScene); break; case Autodesk.Max.IGameObject.ObjectTypes.Unknown: // Create a dummy (empty mesh) when type is unknown // An example of unknown type object is the target of target light or camera babylonNode = ExportDummy(maxGameScene, maxGameNode, babylonScene); break; default: // The type of node is not exportable (helper, spline, xref...) break; } CheckCancelled(); // If node is not exported successfully but is significant if (babylonNode == null && isNodeRelevantToExport(maxGameNode)) { // Create a dummy (empty mesh) babylonNode = ExportDummy(maxGameScene, maxGameNode, babylonScene); } ; if (babylonNode != null) { string tag = maxGameNode.MaxNode.GetStringProperty("babylonjs_tag", ""); if (tag != "") { babylonNode.tags = tag; } // Export its children for (int i = 0; i < maxGameNode.ChildCount; i++) { var descendant = maxGameNode.GetNodeChild(i); exportNodeRec(descendant, babylonScene, maxGameScene); } babylonScene.NodeMap[babylonNode.id] = babylonNode; } return(babylonNode); }
private List <IIGameNode> getDescendants(IIGameNode maxGameNode) { var maxDescendants = new List <IIGameNode>(); for (int i = 0; i < maxGameNode.ChildCount; i++) { maxDescendants.Add(maxGameNode.GetNodeChild(i)); } return(maxDescendants); }
private void exportNodeRec(IIGameNode maxGameNode, BabylonScene babylonScene, IIGameScene maxGameScene) { BabylonNode babylonNode = null; bool hasExporter = true; switch (maxGameNode.IGameObject.IGameType) { case Autodesk.Max.IGameObject.ObjectTypes.Mesh: babylonNode = ExportMesh(maxGameScene, maxGameNode, babylonScene); break; case Autodesk.Max.IGameObject.ObjectTypes.Camera: babylonNode = ExportCamera(maxGameScene, maxGameNode, babylonScene); break; case Autodesk.Max.IGameObject.ObjectTypes.Light: babylonNode = ExportLight(maxGameScene, maxGameNode, babylonScene); break; case Autodesk.Max.IGameObject.ObjectTypes.Unknown: // Create a dummy (empty mesh) when type is unknown // An example of unknown type object is the target of target light or camera babylonNode = ExportDummy(maxGameScene, maxGameNode, babylonScene); break; default: // The type of node is not exportable (helper, spline, xref...) hasExporter = false; break; } CheckCancelled(); // If node is not exported successfully but is significant if (babylonNode == null && isNodeRelevantToExport(maxGameNode)) { //if (!hasExporter) //{ // RaiseWarning($"Type '{maxGameNode.IGameObject.IGameType}' of node '{maxGameNode.Name}' has no exporter, an empty node is exported instead", 1); //} // Create a dummy (empty mesh) babylonNode = ExportDummy(maxGameScene, maxGameNode, babylonScene); } ; if (babylonNode != null) { // Export its children for (int i = 0; i < maxGameNode.ChildCount; i++) { var descendant = maxGameNode.GetNodeChild(i); exportNodeRec(descendant, babylonScene, maxGameScene); } } }
private List <IIGameNode> GetRevelantNodes(IIGameSkin skin) { int logRank = 2; // For optimization if (revelantNodesBySkin.ContainsKey(skin)) { return(revelantNodesBySkin[skin]); } List <IIGameNode> revelantNodes = new List <IIGameNode>(); List <IIGameNode> bones = GetBones(skin); // for each bone of the skin, add their parents in the revelantNodes list. foreach (IIGameNode bone in bones) { if (!revelantNodes.Contains(bone)) { revelantNodes.Add(bone); IIGameNode currentNode = bone.NodeParent; while (currentNode != null) { if (!revelantNodes.Contains(currentNode)) { revelantNodes.Add(currentNode); currentNode = currentNode.NodeParent; } else // the node and its parents are already in the list { currentNode = null; } } } } // return an empty list if there is more than one root List <IIGameNode> rootNodes = revelantNodes.FindAll(node => node.NodeParent == null); // should contains only one node if (rootNodes.Count > 1) { string rootNames = ""; foreach (IIGameNode root in rootNodes) { rootNames += $" {root.Name}"; } RaiseError($"More than one root node for the skin: {rootNames}", logRank); RaiseError($"The skin cannot be exported", logRank); return(new List <IIGameNode>()); } // starting from the root, sort the nodes by depth first (add the children before the siblings) List <IIGameNode> sorted = new List <IIGameNode>(); Stack <IIGameNode> siblings = new Stack <IIGameNode>(); // keep the siblings in a LIFO list to add them after the children siblings.Push(rootNodes[0]); while (siblings.Count > 0) { IIGameNode currentNode = siblings.Pop(); if (revelantNodes.Contains(currentNode)) // The node is part of the skeleton { // Add the current node to the sorted list sorted.Add(currentNode); // Add its children to the stack (in reverse order because it's a LIFO) int childCount = currentNode.ChildCount; for (int index = 0; index < childCount; index++) { siblings.Push(currentNode.GetNodeChild(childCount - 1 - index)); } } } revelantNodes = sorted; revelantNodesBySkin.Add(skin, revelantNodes); // Stock the result for optimization return(revelantNodes); }
private List <IIGameNode> GetRelevantNodes(IIGameSkin skin) { int logRank = 2; // For optimization if (relevantNodesBySkin.ContainsKey(skin)) { return(relevantNodesBySkin[skin]); } List <IIGameNode> bones = GetBones(skin); if (bones.Count == 0) { RaiseWarning("Skin has no bones.", logRank); return(new List <IIGameNode>()); } if (bones.Contains(null)) { RaiseError("Skin has bones that are outside of the exported hierarchy.", logRank); RaiseError("The skin cannot be exported", logRank); return(new List <IIGameNode>()); } List <IIGameNode> allHierarchyNodes = null; IIGameNode lowestCommonAncestor = GetLowestCommonAncestor(bones, ref allHierarchyNodes); if (lowestCommonAncestor == null) { RaiseError($"More than one root node for the skin. The skeleton bones need to be part of the same hierarchy.", logRank); RaiseError($"The skin cannot be exported", logRank); return(new List <IIGameNode>()); } // starting from the root, sort the nodes by depth first (add the children before the siblings) List <IIGameNode> sorted = new List <IIGameNode>(); Stack <IIGameNode> siblings = new Stack <IIGameNode>(); // keep the siblings in a LIFO list to add them after the children siblings.Push(lowestCommonAncestor); // add the skeletonroot: // - as a fallback for vertices without any joint weights (although invalid joints could also be "ok"?) // - to have easy access to the root node for the gltf's [skin.skeleton] property (skeleton root node) // [##onlyBones] commented for now because uncertain if it will work with babylon bone exports //sorted.Add(lowestCommonAncestor); while (siblings.Count > 0) { IIGameNode currentNode = siblings.Pop(); if (allHierarchyNodes.Contains(currentNode)) // The node is part of the skeleton hierarchy { // only add if the node is an actual bone (to keep the joint list small) // [##onlyBones] commented for now because uncertain if it will work with babylon bone exports //if (bones.Contains(currentNode)) sorted.Add(currentNode); // Add its children to the stack (in reverse order because it's a LIFO) int childCount = currentNode.ChildCount; for (int index = 0; index < childCount; index++) { siblings.Push(currentNode.GetNodeChild(childCount - 1 - index)); } } } relevantNodesBySkin.Add(skin, sorted); // Stock the result for optimization return(sorted); }