Пример #1
0
        public static void SaveDataToContainerHelper(IIContainerObject iContainerObject)
        {
            if (!iContainerObject.IsOpen)
            {
                MessageBox.Show("Animations of " + iContainerObject.ContainerNode.Name + " cannot be saved because Container is closed");
                return;
            }

            AnimationGroupList animationGroupList = new AnimationGroupList();

            animationGroupList.LoadFromData(Loader.Core.RootNode);

            RemoveDataOnContainer(iContainerObject); //cleanup for a new serialization
            List <string> animationPropertyNameList = new List <string>();

            foreach (AnimationGroup animationGroup in animationGroupList)
            {
                IIContainerObject containerObject = animationGroup.NodeGuids.InSameContainer();
                if (containerObject != null && containerObject.ContainerNode.Handle == iContainerObject.ContainerNode.Handle)
                {
                    string prop = Loader.Core.RootNode.GetStringProperty(animationGroup.GetPropertyName(), "");
                    containerObject.BabylonContainerHelper().SetStringProperty(animationGroup.GetPropertyName(), prop);
                    animationPropertyNameList.Add(animationGroup.GetPropertyName());
                }
            }

            if (animationPropertyNameList.Count > 0)
            {
                iContainerObject.BabylonContainerHelper().SetStringArrayProperty(s_AnimationListPropertyName, animationPropertyNameList);
            }
        }
Пример #2
0
        public string RenameAnimationGroup(AnimationGroup info, string name)
        {
            AnimationGroupList animationGroupList = new AnimationGroupList();

            animationGroupList.LoadFromData();

            AnimationGroup animGroupToRename = animationGroupList.GetAnimationGroupByName(info.Name);

            string baseName    = name;
            int    i           = 0;
            bool   hasConflict = true;

            while (hasConflict)
            {
                hasConflict = false;
                foreach (AnimationGroup animationGroup in animationGroupList)
                {
                    if (baseName.Equals(animationGroup.Name))
                    {
                        baseName = name + i.ToString();
                        ++i;
                        hasConflict = true;
                        break;
                    }
                }
            }

            animGroupToRename.Name = baseName;

            // save info and animation list entry
            animationGroupList.SaveToData();
            Loader.Global.SetSaveRequiredFlag(true, false);
            return(baseName);
        }
Пример #3
0
        public static void LoadDataFromAnimationHelpers()
        {
            AnimationGroupList sceneAnimationGroupList = new AnimationGroupList();

            sceneAnimationGroupList.LoadFromData();

            foreach (IINode node in Loader.Core.RootNode.DirectChildren())
            {
                if (node.IsBabylonAnimationHelper())
                {
                    AnimationGroupList helperAnimationGroupList = new AnimationGroupList();
                    helperAnimationGroupList.LoadFromData(node);

                    //merge
                    foreach (AnimationGroup animationGroup in helperAnimationGroupList)
                    {
                        AnimationGroup toMerge = sceneAnimationGroupList.Find(a => a.Name == animationGroup.Name);
                        if (toMerge != null)
                        {
                            toMerge.MergeFrom(animationGroup);
                        }
                        else
                        {
                            AnimationGroup newAnimationGroup = new AnimationGroup();
                            newAnimationGroup.DeepCopyFrom(animationGroup);
                            sceneAnimationGroupList.Add(newAnimationGroup);
                        }
                    }
                }
            }
            sceneAnimationGroupList.SaveToData();
            Loader.Global.SetSaveRequiredFlag(true, false);
        }
Пример #4
0
        public static AnimationGroupList InitAnimationGroups(ILoggingProvider logger)
        {
            AnimationGroupList animationList = new AnimationGroupList();

            animationList.LoadFromData(Loader.Core.RootNode);

            if (animationList.Count > 0)
            {
                int timelineStart = Loader.Core.AnimRange.Start / Loader.Global.TicksPerFrame;
                int timelineEnd   = Loader.Core.AnimRange.End / Loader.Global.TicksPerFrame;

                List <string> warnings = new List <string>();
                foreach (AnimationGroup animGroup in animationList)
                {
                    // ensure min <= start <= end <= max
                    warnings.Clear();
                    if (animGroup.FrameStart < timelineStart || animGroup.FrameStart > timelineEnd)
                    {
                        warnings.Add("Start frame '" + animGroup.FrameStart + "' outside of timeline range [" + timelineStart + ", " + timelineEnd + "]. Set to timeline start time '" + timelineStart + "'");
                        animGroup.FrameStart = timelineStart;
                    }
                    if (animGroup.FrameEnd < timelineStart || animGroup.FrameEnd > timelineEnd)
                    {
                        warnings.Add("End frame '" + animGroup.FrameEnd + "' outside of timeline range [" + timelineStart + ", " + timelineEnd + "]. Set to timeline end time '" + timelineEnd + "'");
                        animGroup.FrameEnd = timelineEnd;
                    }
                    if (animGroup.FrameEnd <= animGroup.FrameStart)
                    {
                        if (animGroup.FrameEnd < animGroup.FrameStart)
                        {
                            // Strict
                            warnings.Add("End frame '" + animGroup.FrameEnd + "' lower than Start frame '" + animGroup.FrameStart + "'. Start frame set to timeline start time '" + timelineStart + "'. End frame set to timeline end time '" + timelineEnd + "'.");
                        }
                        else
                        {
                            // Equal
                            warnings.Add("End frame '" + animGroup.FrameEnd + "' equal to Start frame '" + animGroup.FrameStart + "'. Single frame animation are not allowed. Start frame set to timeline start time '" + timelineStart + "'. End frame set to timeline end time '" + timelineEnd + "'.");
                        }

                        animGroup.FrameStart = timelineStart;
                        animGroup.FrameEnd   = timelineEnd;
                    }

                    // Print animation group warnings if any
                    // Nothing printed otherwise
                    if (warnings.Count > 0)
                    {
                        logger.RaiseWarning(animGroup.Name, 1);
                        foreach (string warning in warnings)
                        {
                            logger.RaiseWarning(warning, 2);
                        }
                    }
                }
            }

            return(animationList);
        }
Пример #5
0
        public static void ImportAnimationGroups(string jsonPath)
        {
            AnimationGroupList animationGroups = new AnimationGroupList();
            var fileStream = File.Open(jsonPath, FileMode.Open);

            using (StreamReader reader = new StreamReader(fileStream))
            {
                string jsonContent = reader.ReadToEnd();
                animationGroups.LoadFromJson(jsonContent);
            }
        }
Пример #6
0
        public static bool IsInAnimationGroups(this IINode node, AnimationGroupList animationGroupList)
        {
            foreach (AnimationGroup animationGroup in animationGroupList)
            {
                if (animationGroup.NodeGuids.Contains(node.GetIINodeGuid()))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #7
0
        public static void MergeAnimationGroups(string jsonPath, string old_root, string new_root)
        {
            AnimationGroupList animationGroups = new AnimationGroupList();
            var fileStream = File.Open(jsonPath, FileMode.Open);

            using (StreamReader reader = new StreamReader(fileStream))
            {
                string jsonContent          = reader.ReadToEnd();
                string textToFind           = string.Format(@"\b{0}\b", old_root);
                string overridedJsonContent = Regex.Replace(jsonContent, textToFind, new_root);
                animationGroups.LoadFromJson(overridedJsonContent, true);
            }
        }
Пример #8
0
        public void ExportClosedContainers()
        {
            List <IIContainerObject> sceneContainers = Tools.GetAllContainers();

            foreach (IIContainerObject containerObject in sceneContainers)
            {
                if (!containerObject.IsInherited)
                {
                    continue;
                }
                bool merge = containerObject.MergeSource;
            }
            AnimationGroupList.LoadDataFromContainers();
        }
        public AnimationGroup GetAnimationGroupByName(string name)
        {
            AnimationGroupList animationGroupList = new AnimationGroupList();
            animationGroupList.LoadFromData();

            foreach (AnimationGroup animationGroup in animationGroupList)
            {
                if (animationGroup.Name == name)
                {
                    return animationGroup;
                }
            }

            return null;
        }
Пример #10
0
        public void FlattenHierarchy(IINode node)
        {
            IINode             hierachyRoot       = (node != null) ? node : Loader.Core.RootNode;
            AnimationGroupList animationGroupList = new AnimationGroupList();

            animationGroupList.LoadFromData();

            List <IINode> flattenableNodes = new List <IINode>();

            IsMeshFlattenable(hierachyRoot, animationGroupList, ref flattenableNodes);

            foreach (IINode flattenableNode in flattenableNodes)
            {
                flattenableNode.FlattenHierarchy();
            }
        }
Пример #11
0
        public override bool ExecuteAction()
        {
            var selectedContainers = Tools.GetContainerInSelection();

            if (selectedContainers?.Count <= 0)
            {
                AnimationGroupList.LoadDataFromAnimationHelpers();
                return(true);
            }

            foreach (IIContainerObject containerObject in selectedContainers)
            {
                AnimationGroupList.LoadDataFromContainerHelper(containerObject);
            }

            return(true);
        }
Пример #12
0
        public override bool ExecuteAction()
        {
            if (Loader.Core.SelNodeCount == 0)
            {
                MessageBox.Show("No Container selected");
                return(false);
            }

#if MAX2020
            IINodeTab selection = Loader.Global.INodeTab.Create();
#else
            IINodeTab selection = Loader.Global.INodeTabNS.Create();
#endif
            Loader.Core.GetSelNodeTab(selection);
            List <IIContainerObject> selectedContainers = new List <IIContainerObject>();

            for (int i = 0; i < selection.Count; i++)
            {
#if MAX2015
                var selectedNode = selection[(IntPtr)i];
#else
                var selectedNode = selection[i];
#endif

                IIContainerObject containerObject = Loader.Global.ContainerManagerInterface.IsContainerNode(selectedNode);
                if (containerObject != null)
                {
                    selectedContainers.Add(containerObject);
                }
            }

            if (selectedContainers.Count <= 0)
            {
                MessageBox.Show("No Container selected");
                return(false);
            }

            foreach (IIContainerObject containerObject in selectedContainers)
            {
                AnimationGroupList.SaveDataToContainer(containerObject);
            }


            return(true);
        }
Пример #13
0
        public override bool ExecuteAction()
        {
            Tools.InitializeGuidNodesMap();
            var selectedContainers = Tools.GetContainerInSelection();

            if (selectedContainers.Count <= 0)
            {
                AnimationGroupList.SaveDataToAnimationHelper();
                return(true);
            }

            foreach (IIContainerObject containerObject in selectedContainers)
            {
                AnimationGroupList.SaveDataToContainerHelper(containerObject);
            }

            return(true);
        }
Пример #14
0
        public static void SaveDataToContainers()
        {
            //on scene close automatically move serialization to affected containers
            // look on each animation group if all node are in same container
            // copy property to container

            List <IIContainerObject> containers = Tools.GetAllContainers();

            if (containers.Count <= 0)
            {
                return;
            }

            AnimationGroupList animationGroupList = new AnimationGroupList();

            animationGroupList.LoadFromData();

            foreach (IIContainerObject iContainerObject in containers)
            {
                if (!iContainerObject.IsOpen)
                {
                    MessageBox.Show("Animations of " + iContainerObject.ContainerNode.Name + " cannot be saved because Container is closed");
                    continue;
                }

                RemoveDataOnContainer(iContainerObject); //cleanup for a new serialization
                List <string> animationPropertyNameList = new List <string>();
                foreach (AnimationGroup animationGroup in animationGroupList)
                {
                    IIContainerObject containerObject = animationGroup.NodeGuids.InSameContainer();
                    if (containerObject != null && containerObject.ContainerNode.Handle == iContainerObject.ContainerNode.Handle)
                    {
                        string prop = Loader.Core.RootNode.GetStringProperty(animationGroup.GetPropertyName(), "");
                        containerObject.BabylonContainerHelper().SetStringProperty(animationGroup.GetPropertyName(), prop);
                        animationPropertyNameList.Add(animationGroup.GetPropertyName());
                    }
                }

                if (animationPropertyNameList.Count > 0)
                {
                    iContainerObject.BabylonContainerHelper().SetStringArrayProperty(s_AnimationListPropertyName, animationPropertyNameList);
                }
            }
        }
Пример #15
0
        public void AutoAssignLodInAnimationGroup()
        {
            AnimationGroupList animationGroupList = new AnimationGroupList();

            animationGroupList.LoadFromData();

            var nodes = Loader.Core.RootNode.NodeTree();

            List <IINode> nodeToAdd = new List <IINode>();

            foreach (AnimationGroup anim in animationGroupList)
            {
                nodeToAdd.Clear();
                foreach (Guid guid in anim.NodeGuids)
                {
                    IINode n = Tools.GetINodeByGuid(guid);
                    if (n == null)
                    {
                        continue;
                    }
                    if (!Regex.IsMatch(n.Name, "(?i)x[0-9]_"))
                    {
                        continue;
                    }
                    string noLodName = n.Name.Substring(3);
                    foreach (IINode node in nodes)
                    {
                        if (Regex.IsMatch(node.Name, $"(?i)x[0-9]_{noLodName}$"))
                        {
                            nodeToAdd.Add(node);
                        }
                    }
                }

                foreach (IINode n in nodeToAdd)
                {
                    List <Guid> newGuids = anim.NodeGuids.ToList();
                    newGuids.Add(n.GetGuid());
                    anim.NodeGuids = newGuids;
                }
                anim.SaveToData();
            }
        }
Пример #16
0
        public static void SaveDataToAnimationHelper()
        {
            AnimationGroupList animationGroupList = new AnimationGroupList();

            animationGroupList.LoadFromData(Loader.Core.RootNode);

            List <string> animationPropertyNameList = new List <string>();
            var           helper = Tools.BabylonAnimationHelper();

            foreach (AnimationGroup animationGroup in animationGroupList)
            {
                string prop = Loader.Core.RootNode.GetStringProperty(animationGroup.GetPropertyName(), "");
                helper.SetStringProperty(animationGroup.GetPropertyName(), prop);
                animationPropertyNameList.Add(animationGroup.GetPropertyName());
            }

            if (animationPropertyNameList.Count > 0)
            {
                helper.SetStringArrayProperty(s_AnimationListPropertyName, animationPropertyNameList);
            }
        }
Пример #17
0
        public AnimationGroup CreateAnimationGroup()
        {
            AnimationGroupList animationGroupList = new AnimationGroupList();

            animationGroupList.LoadFromData();

            AnimationGroup info = new AnimationGroup();

            // get a unique name and guid
            string baseName    = info.Name;
            int    i           = 0;
            bool   hasConflict = true;

            while (hasConflict)
            {
                hasConflict = false;
                foreach (AnimationGroup animationGroup in animationGroupList)
                {
                    if (info.Name.Equals(animationGroup.Name))
                    {
                        info.Name = baseName + i.ToString();
                        ++i;
                        hasConflict = true;
                        break;
                    }
                    if (info.SerializedId.Equals(animationGroup.SerializedId))
                    {
                        info.SerializedId = Guid.NewGuid();
                        hasConflict       = true;
                        break;
                    }
                }
            }

            // save info and animation list entry
            animationGroupList.Add(info);
            animationGroupList.SaveToData();
            Loader.Global.SetSaveRequiredFlag(true, false);
            return(info);
        }
        private void ExportAnimationGroups(GLTF gltf, BabylonScene babylonScene)
        {
            AnimationGroupList animationList = new AnimationGroupList();

            animationList.LoadFromData();

            gltf.AnimationsList.Clear();
            gltf.AnimationsList.Capacity = Math.Max(gltf.AnimationsList.Capacity, animationList.Count);

            foreach (AnimationGroup animGroup in animationList)
            {
                GLTFAnimation gltfAnimation = new GLTFAnimation();
                gltfAnimation.name = animGroup.Name;
                foreach (uint nodeHandle in animGroup.NodeHandles)
                {
                    // todo: make something a little more efficient..
                    IINode      maxNode     = Loader.Core.RootNode.FindChildNode(nodeHandle);
                    string      id          = maxNode.GetGuid().ToString();
                    BabylonNode babylonNode = babylonNodes.Find(node => node.id.Equals(id));

                    if (babylonNode != null && nodeToGltfNodeMap.TryGetValue(babylonNode, out GLTFNode gltfNode))
                    {
                        ExportNodeAnimation(gltfAnimation, animGroup.FrameStart, animGroup.FrameEnd, gltf, babylonNode, gltfNode, babylonScene);
                    }

                    // export all bones that match this id
                    foreach (KeyValuePair <BabylonBone, GLTFNode> pair in boneToGltfNodeMap)
                    {
                        if (pair.Key.id.Equals(id))
                        {
                            ExportBoneAnimation(gltfAnimation, animGroup.FrameStart, animGroup.FrameEnd, gltf, pair.Key, pair.Value);
                        }
                    }
                }
                gltf.AnimationsList.Add(gltfAnimation);
            }
        }
Пример #19
0
        private IList <BabylonAnimationGroup> ExportAnimationGroups(BabylonScene babylonScene)
        {
            IList <BabylonAnimationGroup> animationGroups = new List <BabylonAnimationGroup>();

            // Retrieve and parse animation group data
            AnimationGroupList animationList = InitAnimationGroups();

            foreach (AnimationGroup animGroup in animationList)
            {
                RaiseMessage("Exporter.animationGroups | " + animGroup.Name, 1);

                BabylonAnimationGroup animationGroup = new BabylonAnimationGroup
                {
                    name = animGroup.Name,
                    from = animGroup.FrameStart,
                    to   = animGroup.FrameEnd,
                    targetedAnimations = new List <BabylonTargetedAnimation>()
                };

                // add animations of each nodes contained in the animGroup
                foreach (uint nodeHandle in animGroup.NodeHandles)
                {
                    IINode maxNode = Loader.Core.RootNode.FindChildNode(nodeHandle);

                    // node could have been deleted, silently ignore it
                    if (maxNode == null)
                    {
                        continue;
                    }


                    // Helpers can be exported as dummies and as bones
                    string nodeId = maxNode.GetGuid().ToString();
                    string boneId = maxNode.GetGuid().ToString() + "-bone";   // the suffix "-bone" is added in babylon export format to assure the uniqueness of IDs


                    // Node
                    BabylonNode node = babylonScene.MeshesList.FirstOrDefault(m => m.id == nodeId);
                    if (node == null)
                    {
                        node = babylonScene.CamerasList.FirstOrDefault(c => c.id == nodeId);
                    }
                    if (node == null)
                    {
                        node = babylonScene.LightsList.FirstOrDefault(l => l.id == nodeId);
                    }

                    if (node != null)
                    {
                        if (node.animations != null && node.animations.Length != 0)
                        {
                            IList <BabylonAnimation> animations = GetSubAnimations(node, animationGroup.from, animationGroup.to);
                            foreach (BabylonAnimation animation in animations)
                            {
                                BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                                {
                                    animation = animation,
                                    targetId  = nodeId
                                };

                                animationGroup.targetedAnimations.Add(targetedAnimation);
                            }
                        }
                        else if (exportNonAnimated)
                        {
                            BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                            {
                                animation = CreatePositionAnimation(animationGroup.from, animationGroup.to, node.position),
                                targetId  = node.id
                            };

                            animationGroup.targetedAnimations.Add(targetedAnimation);
                        }
                    }

                    // bone
                    BabylonBone bone  = null;
                    int         index = 0;
                    while (index < babylonScene.SkeletonsList.Count && bone == null)
                    {
                        BabylonSkeleton skel = babylonScene.SkeletonsList[index];
                        bone = skel.bones.FirstOrDefault(b => b.id == boneId);
                        index++;
                    }

                    if (bone != null)
                    {
                        if (bone.animation != null)
                        {
                            IList <BabylonAnimation> animations = GetSubAnimations(bone, animationGroup.from, animationGroup.to);
                            foreach (BabylonAnimation animation in animations)
                            {
                                BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                                {
                                    animation = animation,
                                    targetId  = boneId
                                };

                                animationGroup.targetedAnimations.Add(targetedAnimation);
                            }
                        }
                        else if (exportNonAnimated)
                        {
                            BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                            {
                                animation = CreateMatrixAnimation(animationGroup.from, animationGroup.to, bone.matrix),
                                targetId  = bone.id
                            };

                            animationGroup.targetedAnimations.Add(targetedAnimation);
                        }
                    }
                }

                if (animationGroup.targetedAnimations.Count > 0)
                {
                    animationGroups.Add(animationGroup);
                }
            }

            return(animationGroups);
        }
Пример #20
0
        public static AnimationGroupList InitAnimationGroups(ILoggingProvider logger)
        {
            AnimationGroupList animationList = new AnimationGroupList();

            animationList.LoadFromData(Loader.Core.RootNode);

            if (animationList.Count > 0)
            {
                int timelineStart = Loader.Core.AnimRange.Start / Loader.Global.TicksPerFrame;
                int timelineEnd   = Loader.Core.AnimRange.End / Loader.Global.TicksPerFrame;

                List <string> warnings = new List <string>();
                foreach (AnimationGroup animGroup in animationList)
                {
                    // ensure min <= start <= end <= max
                    warnings.Clear();
                    if (animGroup.FrameStart < timelineStart || animGroup.FrameStart > timelineEnd)
                    {
                        warnings.Add("Start frame '" + animGroup.FrameStart + "' outside of timeline range [" + timelineStart + ", " + timelineEnd + "]. Set to timeline start time '" + timelineStart + "'");
                        animGroup.FrameStart = timelineStart;
                    }
                    if (animGroup.FrameEnd < timelineStart || animGroup.FrameEnd > timelineEnd)
                    {
                        warnings.Add("End frame '" + animGroup.FrameEnd + "' outside of timeline range [" + timelineStart + ", " + timelineEnd + "]. Set to timeline end time '" + timelineEnd + "'");
                        animGroup.FrameEnd = timelineEnd;
                    }
                    if (animGroup.FrameEnd <= animGroup.FrameStart)
                    {
                        if (animGroup.FrameEnd < animGroup.FrameStart)
                        {
                            // Strict
                            warnings.Add("End frame '" + animGroup.FrameEnd + "' lower than Start frame '" + animGroup.FrameStart + "'. Start frame set to timeline start time '" + timelineStart + "'. End frame set to timeline end time '" + timelineEnd + "'.");
                        }
                        else
                        {
                            // Equal
                            warnings.Add("End frame '" + animGroup.FrameEnd + "' equal to Start frame '" + animGroup.FrameStart + "'. Single frame animation are not allowed. Start frame set to timeline start time '" + timelineStart + "'. End frame set to timeline end time '" + timelineEnd + "'.");
                        }

                        animGroup.FrameStart = timelineStart;
                        animGroup.FrameEnd   = timelineEnd;
                    }
                    foreach (Guid guid in animGroup.NodeGuids)
                    {
                        IINode node = Tools.GetINodeByGuid(guid);
                        if (node != null)
                        {
                            if (!(node.TMController.IsKeyAtTime(animGroup.TicksStart, (1 << 0)) || node.TMController.IsKeyAtTime(animGroup.TicksStart, (1 << 1)) || node.TMController.IsKeyAtTime(animGroup.TicksStart, (1 << 2))))
                            {
                                int    key = animGroup.TicksStart / 160;
                                string msg = string.Format("Node {0} has no key on min frame: {1} of animation group {2}", node.NodeName, key, animGroup.Name);
                                warnings.Add(msg);
                            }
                            if (!(node.TMController.IsKeyAtTime(animGroup.TicksEnd, (1 << 0)) || node.TMController.IsKeyAtTime(animGroup.TicksEnd, (1 << 1)) || node.TMController.IsKeyAtTime(animGroup.TicksEnd, (1 << 2))))
                            {
                                int    key = animGroup.TicksEnd / 160;
                                string msg = string.Format("Node {0} has no key on max frame: {1} of animation group {2}", node.NodeName, key, animGroup.Name);
                                warnings.Add(msg);
                            }
                        }
                    }

                    // Print animation group warnings if any
                    // Nothing printed otherwise
                    if (warnings.Count > 0)
                    {
                        logger.RaiseWarning(animGroup.Name, 1);
                        foreach (string warning in warnings)
                        {
                            logger.RaiseWarning(warning, 2);
                        }
                    }
                }
            }

            return(animationList);
        }
Пример #21
0
 public override bool ExecuteAction()
 {
     AnimationGroupList.LoadDataFromContainers();
     return(true);
 }
Пример #22
0
 public override bool ExecuteAction()
 {
     AnimationGroupList.SaveDataToContainers();
     return(true);
 }
Пример #23
0
        private void IsMeshFlattenable(IINode node, AnimationGroupList animationGroupList, ref List <IINode> flattenableNodes)
        {
            //a node can't be flatten if:
            //- is not a mesh
            //- is marked as not flattenable
            //- is hidden
            //- is part of animation group
            //- is skinned
            //- is linked to animated node

            if (node.IsMarkedAsNotFlattenable())
            {
                return;
            }

            if (node.IsNodeHidden(false) && !exportParameters.exportHiddenObjects)
            {
                return;
            }

            if (node.IsRootNode)
            {
                for (int i = 0; i < node.NumChildren; i++)
                {
                    IINode n = node.GetChildNode(i);
                    IsMeshFlattenable(n, animationGroupList, ref flattenableNodes);
                }
                return;
            }

            if (node.GetTriObjectFromNode() == null)
            {
                for (int i = 0; i < node.NumChildren; i++)
                {
                    IINode n = node.GetChildNode(i);
                    IsMeshFlattenable(n, animationGroupList, ref flattenableNodes);
                }
                return;
            }

            if (node.IsSkinned())
            {
                string message = $"{node.Name} can't be flatten, because is skinned";
                RaiseMessage(message, 0);
                for (int i = 0; i < node.NumChildren; i++)
                {
                    IINode n = node.GetChildNode(i);
                    IsMeshFlattenable(n, animationGroupList, ref flattenableNodes);
                }
                return;
            }

            if (node.IsInAnimationGroups(animationGroupList))
            {
                string message = $"{node.Name} can't be flatten, because is part of an AnimationGroup";
                RaiseMessage(message, 0);
                for (int i = 0; i < node.NumChildren; i++)
                {
                    IINode n = node.GetChildNode(i);
                    IsMeshFlattenable(n, animationGroupList, ref flattenableNodes);
                }
                return;
            }

            if (node.IsNodeTreeAnimated())
            {
                string message = $"{node.Name} can't be flatten, his hierachy contains animated node";
                RaiseMessage(message, 0);
                for (int i = 0; i < node.NumChildren; i++)
                {
                    IINode n = node.GetChildNode(i);
                    IsMeshFlattenable(n, animationGroupList, ref flattenableNodes);
                }
                return;
            }

            flattenableNodes.Add(node);
        }
Пример #24
0
        private IList <BabylonAnimationGroup> ExportAnimationGroups(BabylonScene babylonScene)
        {
            IList <BabylonAnimationGroup> animationGroups = new List <BabylonAnimationGroup>();

            // Retrieve and parse animation group data
            AnimationGroupList animationList = AnimationGroupList.InitAnimationGroups(logger);

            foreach (AnimationGroup animGroup in animationList)
            {
                logger?.RaiseMessage("Exporter.animationGroups | " + animGroup.Name, 1);
                BabylonAnimationGroup animationGroup = new BabylonAnimationGroup
                {
                    name               = animGroup.Name,
                    from               = animGroup.FrameStart,
                    to                 = animGroup.FrameEnd,
                    keepNonAnimated    = animGroup.KeepNonAnimated,
                    targetedAnimations = new List <BabylonTargetedAnimation>()
                };

                // add animations of each nodes contained in the animGroup
                foreach (Guid guid in animGroup.NodeGuids)
                {
                    IINode maxNode = Tools.GetINodeByGuid(guid);

                    // node could have been deleted, silently ignore it
                    if (maxNode == null)
                    {
                        continue;
                    }

                    if (exportParameters.exportAsSubmodel && !maxNode.Selected)
                    {
                        continue;
                    }


                    // Helpers can be exported as dummies and as bones
                    string nodeId = maxNode.GetGuid().ToString();
                    string boneId = isGltfExported?maxNode.GetGuid().ToString(): maxNode.GetGuid().ToString() + "-bone";   // the suffix "-bone" is added in babylon export format to assure the uniqueness of IDs

                    // Node
                    BabylonNode node = null;
                    babylonScene.NodeMap.TryGetValue(nodeId, out node);
                    if (node != null)
                    {
                        if (node.animations != null && node.animations.Length != 0)
                        {
                            IList <BabylonAnimation> animations = GetSubAnimations(node, animationGroup.from, animationGroup.to);

                            if (!animGroup.KeepStaticAnimation)
                            {
                                RemoveStaticAnimations(ref animations);
                            }

                            foreach (BabylonAnimation animation in animations)
                            {
                                BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                                {
                                    animation = animation,
                                    targetId  = nodeId
                                };

                                animationGroup.targetedAnimations.Add(targetedAnimation);
                            }
                        }
                    }

                    // bone
                    BabylonBone bone  = null;
                    int         index = 0;
                    while (index < babylonScene.SkeletonsList.Count && bone == null)
                    {
                        BabylonSkeleton skel = babylonScene.SkeletonsList[index];
                        bone = skel.bones.FirstOrDefault(b => b.id == boneId);
                        index++;
                    }

                    if (bone != null)
                    {
                        if (bone.animation != null)
                        {
                            IList <BabylonAnimation> animations = GetSubAnimations(bone, animationGroup.from, animationGroup.to);
                            foreach (BabylonAnimation animation in animations)
                            {
                                BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                                {
                                    animation = animation,
                                    targetId  = boneId
                                };

                                animationGroup.targetedAnimations.Add(targetedAnimation);
                            }
                        }
                    }
                }

                // add animations of each nodes contained in the animGroup
                foreach (Guid guid in animGroup.MaterialGuids)
                {
                    IMtl maxMtl = Tools.GetIMtlByGuid(guid);

                    // mat could have been deleted, silently ignore it
                    if (maxMtl == null)
                    {
                        continue;
                    }

                    string matId = maxMtl.GetGuid().ToString();

                    // Material
                    BabylonMaterial material = null;
                    material = babylonScene.MaterialsList.FirstOrDefault(x => x.id == matId);
                    if (material != null)
                    {
                        if (material.animations != null && material.animations.Length != 0)
                        {
                            IList <BabylonAnimation> animations = GetSubAnimations(material, animationGroup.from, animationGroup.to);
                            foreach (BabylonAnimation animation in animations)
                            {
                                BabylonTargetedAnimation targetedAnimation = new BabylonTargetedAnimation
                                {
                                    animation = animation,
                                    targetId  = matId
                                };

                                animationGroup.targetedAnimations.Add(targetedAnimation);
                            }
                        }
                    }
                }

                if (animationGroup.targetedAnimations.Count > 0)
                {
                    animationGroups.Add(animationGroup);
                }
            }

            return(animationGroups);
        }
Пример #25
0
        private void ExportAnimationGroups(GLTF gltf, BabylonScene babylonScene)
        {
            // Retreive and parse animation group data
            AnimationGroupList animationList = InitAnimationGroups();

            gltf.AnimationsList.Clear();
            gltf.AnimationsList.Capacity = Math.Max(gltf.AnimationsList.Capacity, animationList.Count);

            if (animationList.Count <= 0)
            {
                RaiseMessage("GLTFExporter.Animation | No AnimationGroups: exporting all animations together.", 1);
                GLTFAnimation gltfAnimation = new GLTFAnimation();
                gltfAnimation.name = "All Animations";

                int minFrame = Loader.Core.AnimRange.Start / Loader.Global.TicksPerFrame;
                int maxFrame = Loader.Core.AnimRange.End / Loader.Global.TicksPerFrame;

                foreach (var pair in nodeToGltfNodeMap)
                {
                    ExportNodeAnimation(gltfAnimation, minFrame, maxFrame, gltf, pair.Key, pair.Value, babylonScene);
                }
                foreach (var pair in boneToGltfNodeMap)
                {
                    ExportBoneAnimation(gltfAnimation, minFrame, maxFrame, gltf, pair.Key, pair.Value);
                }

                if (gltfAnimation.ChannelList.Count > 0)
                {
                    gltf.AnimationsList.Add(gltfAnimation);
                }
                else
                {
                    RaiseMessage("GLTFExporter.Animation | No animation data for this animation, it is ignored.", 2);
                }
            }
            else
            {
                foreach (AnimationGroup animGroup in animationList)
                {
                    RaiseMessage("GLTFExporter.Animation | " + animGroup.Name, 1);

                    GLTFAnimation gltfAnimation = new GLTFAnimation();
                    gltfAnimation.name = animGroup.Name;

                    int startFrame = animGroup.FrameStart;
                    int endFrame   = animGroup.FrameEnd;

                    foreach (uint nodeHandle in animGroup.NodeHandles)
                    {
                        // todo: make something a little more efficient..
                        IINode maxNode = Loader.Core.RootNode.FindChildNode(nodeHandle);

                        // node could have been deleted, silently ignore it
                        if (maxNode == null)
                        {
                            continue;
                        }

                        string      id          = maxNode.GetGuid().ToString();
                        BabylonNode babylonNode = babylonNodes.Find(node => node.id.Equals(id));

                        if (babylonNode != null && nodeToGltfNodeMap.TryGetValue(babylonNode, out GLTFNode gltfNode))
                        {
                            ExportNodeAnimation(gltfAnimation, startFrame, endFrame, gltf, babylonNode, gltfNode, babylonScene);
                        }

                        // export all bones that match this id
                        foreach (KeyValuePair <BabylonBone, GLTFNode> pair in boneToGltfNodeMap)
                        {
                            if (pair.Key.id.Equals(id))
                            {
                                ExportBoneAnimation(gltfAnimation, startFrame, endFrame, gltf, pair.Key, pair.Value);
                            }
                        }
                    }

                    if (gltfAnimation.ChannelList.Count > 0)
                    {
                        gltf.AnimationsList.Add(gltfAnimation);
                    }
                    else
                    {
                        RaiseMessage("No data exported for this animation, it is ignored.", 2);
                    }
                }
            }
        }