public void SetModel(Object obj, TextureSet textureSet) { if (!CanRender) { return; } Reset(); mModel = new GLObject(obj, new Dictionary <int, GLTexture>(), textureSet); SetCamera(obj.BoundingSphere); }
public void SetModel(Mesh mesh, Object obj, TextureSet textureSet) { if (!CanRender) { return; } Reset(); var materials = new List <GLMaterial>(new GLMaterial[obj.Materials.Count]); var dictionary = new Dictionary <int, GLTexture>(); foreach (var subMesh in mesh.SubMeshes) { if (materials[subMesh.MaterialIndex] == null) { materials[subMesh.MaterialIndex] = new GLMaterial(obj.Materials[subMesh.MaterialIndex], dictionary, textureSet); } } mModel = new GLMesh(mesh, materials); SetCamera(mesh.BoundingSphere); }
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); }
protected override void Initialize() { RegisterExportHandler <ObjectSet>(filePath => { var configuration = ConfigurationList.Instance.CurrentConfiguration; var objectDatabase = configuration?.ObjectDatabase; var textureDatabase = configuration?.TextureDatabase; var boneDatabase = configuration?.BoneDatabase; Data.Save(filePath, objectDatabase, textureDatabase, boneDatabase); }); RegisterExportHandler <Scene>(filePath => Exporter.ConvertAiSceneFromObjectSet(Data, filePath)); RegisterReplaceHandler <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); }); RegisterReplaceHandler <Scene>(filePath => { if (Data.Objects.Count > 1) { return(Importer.ConvertObjectSetFromAiScene(filePath)); } return(Importer.ConvertObjectSetFromAiSceneWithSingleObject(filePath)); }); RegisterCustomHandler("Rename all shaders to...", () => { using (var inputDialog = new InputDialog { WindowTitle = "Rename all shaders", Input = "BLINN" }) { if (inputDialog.ShowDialog() != DialogResult.OK) { return; } foreach (var material in Data.Objects.SelectMany(x => x.Materials)) { material.Shader = inputDialog.Input; } } IsDirty = true; }); RegisterCustomHandler("Convert triangles to triangle strips", () => { foreach (var subMesh in Data.Objects.SelectMany(x => x.Meshes).SelectMany(x => x.SubMeshes)) { if (subMesh.PrimitiveType == PrimitiveType.Triangles) { var triangleStrip = Stripifier.Stripify(subMesh.Indices); if (triangleStrip != null) { subMesh.PrimitiveType = PrimitiveType.TriangleStrip; subMesh.Indices = triangleStrip; } } } IsDirty = true; }); RegisterCustomHandler("Combine all objects into one", () => { if (Data.Objects.Count <= 1) { return; } 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]]; } } } } } foreach (var subMesh in obj.Meshes.SelectMany(x => x.SubMeshes)) { subMesh.MaterialIndex += combinedObject.Materials.Count; } combinedObject.Meshes.AddRange(obj.Meshes); combinedObject.Materials.AddRange(obj.Materials); } Data.Objects.Clear(); Data.Objects.Add(combinedObject); if (IsPopulated) { IsPopulated = false; Populate(); } IsDirty = true; }); base.Initialize(); }