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); } }
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); }
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); }
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); }
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); } }
public static bool IsInAnimationGroups(this IINode node, AnimationGroupList animationGroupList) { foreach (AnimationGroup animationGroup in animationGroupList) { if (animationGroup.NodeGuids.Contains(node.GetIINodeGuid())) { return(true); } } return(false); }
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); } }
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; }
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(); } }
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); }
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); }
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); }
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); } } }
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(); } }
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); } }
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); } }
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); }
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); }
public override bool ExecuteAction() { AnimationGroupList.LoadDataFromContainers(); return(true); }
public override bool ExecuteAction() { AnimationGroupList.SaveDataToContainers(); return(true); }
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); }
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); }
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); } } } }