private void confirmButton_Click(object sender, EventArgs e) { if (currentInfo == null) { return; } AnimationGroup confirmedInfo = currentInfo; string newName = nameTextBox.Text; bool newKeepEmpty = keepStaticAnimBox.Checked; bool newKeepNonAnimated = keepNonAnimatedBox.Checked; int newFrameStart; if (!int.TryParse(startTextBox.Text, out newFrameStart)) { newFrameStart = confirmedInfo.FrameStart; } int newFrameEnd; if (!int.TryParse(endTextBox.Text, out newFrameEnd)) { newFrameEnd = confirmedInfo.FrameEnd; } List <uint> newHandles; bool nodesChanged = MaxNodeTree.ApplyQueuedChanges(out newHandles); IList <Guid> newMaterialGUIDs; bool materialsChanged = maxMaterialView.ApplyMaterialsChanges(out newMaterialGUIDs); bool changed = newKeepEmpty != confirmedInfo.KeepStaticAnimation || newName != confirmedInfo.Name || newFrameStart != confirmedInfo.FrameStart || newFrameEnd != confirmedInfo.FrameEnd || nodesChanged || materialsChanged || newKeepNonAnimated != confirmedInfo.KeepNonAnimated; if (!changed) { return; } confirmedInfo.Name = newName; confirmedInfo.FrameStart = newFrameStart; confirmedInfo.FrameEnd = newFrameEnd; confirmedInfo.KeepStaticAnimation = newKeepEmpty; confirmedInfo.KeepNonAnimated = newKeepNonAnimated; if (nodesChanged) { confirmedInfo.NodeGuids = newHandles.ToGuids(); if (confirmedInfo.AnimationGroupNodes == null) { confirmedInfo.AnimationGroupNodes = new List <AnimationGroupNode>(); } foreach (uint handle in newHandles) { IINode node = Loader.Core.GetINodeByHandle(handle); if (node != null) { string name = node.Name; string parentName = node.ParentNode.Name; AnimationGroupNode nodeData = new AnimationGroupNode(node.GetGuid(), name, parentName); confirmedInfo.AnimationGroupNodes.Add(nodeData); } } } if (materialsChanged) { confirmedInfo.MaterialGuids = newMaterialGUIDs; if (confirmedInfo.AnimationGroupMaterials == null) { confirmedInfo.AnimationGroupMaterials = new List <AnimationGroupMaterial>(); } foreach (Guid guid in newMaterialGUIDs) { IMtl mat = Tools.GetIMtlByGuid(guid); if (mat != null) { string name = mat.Name; AnimationGroupMaterial matData = new AnimationGroupMaterial(guid, name); confirmedInfo.AnimationGroupMaterials.Add(matData); } } } ResetChangedTextBoxColors(); MaxNodeTree.SelectedNode = null; InfoChanged?.Invoke(confirmedInfo); ConfirmPressed?.Invoke(confirmedInfo); }
public void LoadFromData(string propertyName, IINode dataNode, Dictionary <string, string> rootNodePropDictionary = null) { if (!Guid.TryParse(propertyName, out serializedId)) { throw new Exception("Invalid ID, can't deserialize."); } string propertiesString = string.Empty; if (rootNodePropDictionary == null) { if (!dataNode.GetUserPropString(propertyName, ref propertiesString)) { return; } } else { if (!rootNodePropDictionary.TryGetValue(propertyName, out propertiesString)) { return; } } int numFailed = 0; try // Try using the new way, if it's not working use the old way. { SerializableAnimationGroup serialAnimGroup = new SerializableAnimationGroup(propertiesString); serialAnimGroup.FillSerializedData(this); } catch { int indexOfguidPart = propertiesString .Select((c, i) => new { c, i }) .Where(x => x.c == s_PropertySeparator) .Skip(2) .FirstOrDefault().i; string[] baseProperties = propertiesString.Substring(0, indexOfguidPart)?.Split(s_PropertySeparator); string guidPart = propertiesString.Substring(indexOfguidPart + 1); if (baseProperties.Length != 3) { throw new Exception("Invalid number of properties, can't deserialize."); } // set dirty explicitly just before we start loading, set to false when loading is done // if any exception is thrown, it will have a correct value IsDirty = true; name = baseProperties[0]; if (!int.TryParse(baseProperties[1], out ticksStart)) { throw new Exception("Failed to parse FrameStart property."); } if (!int.TryParse(baseProperties[2], out ticksEnd)) { throw new Exception("Failed to parse FrameEnd property."); } if (string.IsNullOrEmpty(guidPart) || guidPart == s_GUIDTypeSeparator.ToString()) { return; } if (!guidPart.Contains(s_GUIDTypeSeparator)) { // to grant retro-compatiblity numFailed = ParseOldProperties(guidPart); } else { //new format with nodes and node materials guid numFailed = ParseNewProperties(guidPart); } } AnimationGroupNodes = new List <AnimationGroupNode>(); foreach (Guid nodeGuid in nodeGuids) { IINode node = Tools.GetINodeByGuid(nodeGuid); if (node != null) { string name = node.Name; string parentName = node.ParentNode.Name; AnimationGroupNode nodeData = new AnimationGroupNode(nodeGuid, name, parentName); AnimationGroupNodes.Add(nodeData); } } AnimationGroupMaterials = new List <AnimationGroupMaterial>(); foreach (Guid materialGUID in materialsGuids) { IMtl mat = Tools.GetIMtlByGuid(materialGUID); if (mat != null) { string name = mat.Name; AnimationGroupMaterial matData = new AnimationGroupMaterial(materialGUID, name); AnimationGroupMaterials.Add(matData); } } if (numFailed > 0) { throw new Exception(string.Format("Failed to parse {0} node ids.", numFailed)); } IsDirty = false; }
public void LoadFromJson(string jsonContent, bool merge = false) { List <string> animationPropertyNameList = Loader.Core.RootNode.GetStringArrayProperty(s_AnimationListPropertyName).ToList(); if (!merge) { animationPropertyNameList = new List <string>(); Clear(); } List <AnimationGroup> animationGroupsData = JsonConvert.DeserializeObject <List <AnimationGroup> >(jsonContent); List <Guid> nodeGuids = new List <Guid>(); List <Guid> materialsGuids = new List <Guid>(); foreach (AnimationGroup animData in animationGroupsData) { nodeGuids.Clear(); if (animData.AnimationGroupNodes != null) { string missingNodes = ""; string movedNodes = ""; foreach (AnimationGroupNode nodeData in animData.AnimationGroupNodes) { //check here if something changed between export\import // a node handle is reassigned the moment the node is created // it is no possible to have consistency at 100% sure between two file // we need to prevent artists IINode node = Loader.Core.GetINodeByName(nodeData.Name); if (node == null) { //node is missing missingNodes += nodeData.Name + "\n"; continue; } if (node.ParentNode.Name != nodeData.ParentName) { //node has been moved in hierarchy movedNodes += node.Name + "\n"; continue; } nodeGuids.Add(node.GetGuid()); } if (!string.IsNullOrEmpty(movedNodes)) { //skip restoration of evaluated animation group nodeGuids = new List <Guid>(); MessageBox.Show(string.Format("{0} has been moved in hierarchy,{1} import skipped", movedNodes, animData.Name)); } if (!string.IsNullOrEmpty(missingNodes)) { //skip restoration of evaluated animation group nodeGuids = new List <Guid>(); MessageBox.Show(string.Format("{0} does not exist,{1} import skipped", missingNodes, animData.Name)); } } if (animData.AnimationGroupMaterials != null) { string missingMaterials = ""; foreach (AnimationGroupMaterial matData in animData.AnimationGroupMaterials) { //check here if something changed between export\import // a material handle is reassigned the moment the node is created // it is no possible to have consistency at 100% sure between two file // we need to prevent artists IMtl mtl = Tools.GetIMtlByGuid(matData.Guid); if (mtl == null) { //material is missing missingMaterials += matData.Name + "\n"; continue; } materialsGuids.Add(mtl.GetGuid()); } if (!string.IsNullOrEmpty(missingMaterials)) { //skip restoration of evaluated animation group materialsGuids = new List <Guid>(); MessageBox.Show(string.Format("{0} does not exist,{1} import skipped", missingMaterials, animData.Name)); } } animData.NodeGuids = nodeGuids; animData.MaterialGuids = materialsGuids; string nodes = string.Join(AnimationGroup.s_PropertySeparator.ToString(), animData.NodeGuids); string materials = string.Join(AnimationGroup.s_PropertySeparator.ToString(), animData.MaterialGuids); string guids = string.Join(AnimationGroup.s_GUIDTypeSeparator.ToString(), nodes, materials); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendFormat(AnimationGroup.s_PropertyFormat, animData.Name, animData.TicksStart, animData.TicksEnd, guids); Loader.Core.RootNode.SetStringProperty(animData.SerializedId.ToString(), stringBuilder.ToString()); string id = animData.SerializedId.ToString(); if (merge) { //if json are merged check if the same animgroup is already in list //and skip in that case if (!animationPropertyNameList.Contains(id)) { animationPropertyNameList.Add(animData.SerializedId.ToString()); } } else { animationPropertyNameList.Add(animData.SerializedId.ToString()); } } Loader.Core.RootNode.SetStringArrayProperty(s_AnimationListPropertyName, animationPropertyNameList); LoadFromData(Loader.Core.RootNode); }
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); }