Exemple #1
0
        static System.Numerics.Quaternion ConvertQuat(Assimp.Quaternion Q)
        {
            NumMatrix4x4.Decompose(ConvertMatrix(new AssMatrix4x4(Q.GetMatrix())), out Vector3 _S, out System.Numerics.Quaternion Quat, out Vector3 _T);
            return(Quat);

            // return new System.Numerics.Quaternion(Q.X, Q.Y, Q.Z, Q.W);
        }
        protected override void Initialize()
        {
            AddExportHandler <ObjectSet>(filePath =>
            {
                if (filePath.EndsWith(".fbx", StringComparison.OrdinalIgnoreCase))
                {
                    Data.TryFixParentBoneInfos(SourceConfiguration?.BoneDatabase);
                    FbxExporter.ExportToFile(Data, filePath);
                }

                else
                {
                    var configuration = ConfigurationList.Instance.CurrentConfiguration;

                    var objectDatabase  = configuration?.ObjectDatabase;
                    var textureDatabase = configuration?.TextureDatabase;
                    var boneDatabase    = configuration?.BoneDatabase;

                    Data.Save(filePath, objectDatabase, textureDatabase, boneDatabase);
                }
            });
            AddExportHandler <Scene>(filePath =>
            {
                Data.TryFixParentBoneInfos(SourceConfiguration?.BoneDatabase);
                AssimpExporter.ExportToFile(Data, filePath);
            });
            AddReplaceHandler <ObjectSet>(filePath =>
            {
                var configuration = ConfigurationList.Instance.CurrentConfiguration;

                var objectDatabase  = configuration?.ObjectDatabase;
                var textureDatabase = configuration?.TextureDatabase;

                var objectSet = new ObjectSet();
                objectSet.Load(filePath, objectDatabase, textureDatabase);
                return(objectSet);
            });
            AddReplaceHandler <Scene>(filePath =>
            {
                if (Data.Objects.Count > 1)
                {
                    return(AssimpImporter.ImportFromFile(filePath));
                }

                return(AssimpImporter.ImportFromFileWithSingleObject(filePath));
            });

            AddCustomHandler("Copy object set info to clipboard", () =>
            {
                uint objectSetId = 39;
                uint objectId    = 0xFFFFFFFF;

                var objectDatabase = ConfigurationList.Instance.CurrentConfiguration?.ObjectDatabase;

                if (objectDatabase != null && objectDatabase.ObjectSets.Count > 0)
                {
                    objectSetId = objectDatabase.ObjectSets.Max(x => x.Id) + 1;
                    objectId    = objectDatabase.ObjectSets.SelectMany(x => x.Objects).Max(x => x.Id) + 1;
                }

                else
                {
                    using (var inputDialog = new InputDialog
                    {
                        WindowTitle = "Enter base id for objects",
                        Input = Math.Max(0, Data.Objects.Max(x => x.Id) + 1).ToString()
                    })
                    {
                        while (inputDialog.ShowDialog() == DialogResult.OK)
                        {
                            bool result = uint.TryParse(inputDialog.Input, out objectId);

                            if (!result || objectId == 0xFFFFFFFF)
                            {
                                MessageBox.Show("Please enter a correct id number.", Program.Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }

                            else
                            {
                                break;
                            }
                        }
                    }
                }

                if (objectId == 0xFFFFFFFF)
                {
                    return;
                }

                string baseName = Path.ChangeExtension(Name, null);
                if (Data.Format.IsClassic() && baseName.EndsWith("_obj", StringComparison.OrdinalIgnoreCase))
                {
                    baseName = baseName.Substring(0, baseName.Length - 4);
                }

                var objectSetInfo = new ObjectSetInfo
                {
                    Name            = baseName.ToUpperInvariant(),
                    Id              = objectSetId,
                    FileName        = Name,
                    TextureFileName = baseName + (Data.Format.IsClassic() ? "_tex.bin" : ".txd"),
                    ArchiveFileName = Parent is FarcArchiveNode ? Parent.Name : baseName + ".farc"
                };

                foreach (var obj in Data.Objects)
                {
                    objectSetInfo.Objects.Add(new ObjectInfo
                    {
                        Id   = objectId++,
                        Name = obj.Name.ToUpperInvariant()
                    });
                }

                using (var stringWriter = new StringWriter())
                    using (var xmlWriter = XmlWriter.Create(stringWriter,
                                                            new XmlWriterSettings {
                        Indent = true, OmitXmlDeclaration = true
                    }))
                    {
                        sObjectSetInfoSerializer.Serialize(xmlWriter, objectSetInfo,
                                                           new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }));

                        Clipboard.SetText(stringWriter.ToString());
                    }
            });

            AddCustomHandlerSeparator();

            AddDirtyCustomHandler("Combine all objects into one", () =>
            {
                if (Data.Objects.Count <= 1)
                {
                    return(false);
                }

                var combinedObject = new Object {
                    Name = "Combined object"
                };
                var indexMap = new Dictionary <int, int>();

                foreach (var obj in Data.Objects)
                {
                    if (obj.Skin != null)
                    {
                        if (combinedObject.Skin == null)
                        {
                            combinedObject.Skin = new Skin();
                            combinedObject.Skin.Bones.AddRange(obj.Skin.Bones);
                        }

                        else
                        {
                            for (int i = 0; i < obj.Skin.Bones.Count; i++)
                            {
                                var bone      = obj.Skin.Bones[i];
                                int boneIndex = combinedObject.Skin.Bones.FindIndex(
                                    x => x.Name.Equals(bone.Name, StringComparison.OrdinalIgnoreCase));

                                if (boneIndex == -1)
                                {
                                    indexMap[i] = combinedObject.Skin.Bones.Count;
                                    combinedObject.Skin.Bones.Add(bone);
                                }

                                else
                                {
                                    indexMap[i] = boneIndex;
                                }
                            }

                            foreach (var subMesh in obj.Meshes.SelectMany(x => x.SubMeshes))
                            {
                                if (subMesh.BoneIndices?.Length >= 1)
                                {
                                    for (int i = 0; i < subMesh.BoneIndices.Length; i++)
                                    {
                                        subMesh.BoneIndices[i] = ( ushort )indexMap[subMesh.BoneIndices[i]];
                                    }
                                }
                            }
                        }

                        combinedObject.Skin.Blocks.AddRange(obj.Skin.Blocks);
                    }

                    foreach (var subMesh in obj.Meshes.SelectMany(x => x.SubMeshes))
                    {
                        subMesh.MaterialIndex += ( uint )combinedObject.Materials.Count;
                    }

                    combinedObject.Meshes.AddRange(obj.Meshes);
                    combinedObject.Materials.AddRange(obj.Materials);
                }

                Data.Objects.Clear();
                Data.Objects.Add(combinedObject);

                return(true);
            }, Keys.None, CustomHandlerFlags.Repopulate | CustomHandlerFlags.ClearMementos);

            AddCustomHandlerSeparator();

            AddDirtyCustomHandler("Convert all bones to osage", () =>
            {
                foreach (var obj in Data.Objects)
                {
                    var movingBone = obj.Skin?.Bones.FirstOrDefault(x => x.Name == "kl_mune_b_wj");
                    if (movingBone == null)
                    {
                        continue;
                    }

                    var nameMap       = new Dictionary <string, string>();
                    var stringBuilder = new StringBuilder();

                    foreach (var bone in obj.Skin.Bones)
                    {
                        // Ignore bones if they are already OSG or EXP.
                        // Also ignore the moving bone and its parents.

                        // Ignore j_kao_wj for now because it f***s miku's headphones up
                        if (bone.Name == "j_kao_wj")
                        {
                            continue;
                        }

                        var boneToCompare = movingBone;

                        do
                        {
                            if (boneToCompare == bone)
                            {
                                break;
                            }

                            boneToCompare = boneToCompare.Parent;
                        } while (boneToCompare != null);

                        if (boneToCompare == bone)
                        {
                            continue;
                        }

                        if (obj.Skin.Blocks.Any(x =>
                        {
                            switch (x)
                            {
                            case OsageBlock osgBlock:
                                return(osgBlock.Nodes.Any(y => y.Name == bone.Name));

                            case ExpressionBlock expBlock:
                                return(expBlock.Name == bone.Name);

                            default:
                                return(false);
                            }
                        }))
                        {
                            continue;
                        }

                        if (bone.Parent == null)
                        {
                            bone.Parent = movingBone;
                        }

                        Matrix4x4.Invert(bone.InverseBindPoseMatrix, out var bindPoseMatrix);
                        var matrix = Matrix4x4.Multiply(bindPoseMatrix, bone.Parent.InverseBindPoseMatrix);

                        Matrix4x4.Decompose(matrix, out var scale, out var rotation, out var translation);

                        rotation = Quaternion.Normalize(rotation);

                        string newName = bone.Name;

                        if (newName.EndsWith("_wj", StringComparison.OrdinalIgnoreCase))
                        {
                            newName = newName.Remove(newName.Length - 3);
                        }

                        newName += "_ragdoll";

                        nameMap.Add(bone.Name, newName);

                        bone.Name = newName;

                        string baseName = newName;

                        var osageBlock = new OsageBlock
                        {
                            ExternalName = $"c_{baseName}_osg",
                            Name         = $"e_{baseName}",
                            ParentName   = bone.Parent.Name,
                            Position     = translation,
                            Rotation     = rotation.ToEulerAngles(),
                            Scale        = scale
                        };

                        osageBlock.Nodes.Add(new OsageNode {
                            Name = bone.Name, Length = 0.08f
                        });
                        obj.Skin.Blocks.Add(osageBlock);

                        stringBuilder.AppendFormat(
                            "{0}.node.0.coli_r=0.030000\r\n" +
                            "{0}.node.0.hinge_ymax=179.000000\r\n" +
                            "{0}.node.0.hinge_ymin=-179.000000\r\n" +
                            "{0}.node.0.hinge_zmax=179.000000\r\n" +
                            "{0}.node.0.hinge_zmin=-179.000000\r\n" +
                            "{0}.node.0.inertial_cancel=1.000000\r\n" +
                            "{0}.node.0.weight=3.000000\r\n" +
                            "{0}.node.length=1\r\n" +
                            "{0}.root.force=0.010000\r\n" +
                            "{0}.root.force_gain=0.300000\r\n" +
                            "{0}.root.friction=1.000000\r\n" +
                            "{0}.root.init_rot_y=0.000000\r\n" +
                            "{0}.root.init_rot_z=0.000000\r\n" +
                            "{0}.root.rot_y=0.000000\r\n" +
                            "{0}.root.rot_z=0.000000\r\n" +
                            "{0}.root.stiffness=0.100000\r\n" +
                            "{0}.root.wind_afc=0.500000\r\n",
                            osageBlock.ExternalName);
                    }