Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
                }
            }
        }
Exemplo n.º 4
0
        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);
        }