private WhModel LoadWhCharacterModel(WhRace race, WhGender gender, string[] itemIds) { var gathererItems = WhDataLoader.LoadItemsFromGatherer(itemIds); var options = new WhViewerOptions() { Cls = WhClass.WARRIOR, Hd = true }; if (gathererItems != null) { options.Items = gathererItems .Select((x, i) => new WhViewerOptions.Item() { Slot = x.Value.OtherData.SlotBak, Id = x.Value.OtherData.DisplayId, // Пока так, когда узнать откуда взять этот id - надо тоже прописать VisualId = null }) .ToArray(); } var characterModel = new WhModel( options, WhModelInfo.CreateForCharacter(race, gender), 0); WhDefferedList.Execute(); characterModel.EmulateDraw(false); return(characterModel); }
private WhModel LoadWhCharacterModel(WhViewerOptions opts) { var characterModel = new WhModel( opts, opts.Model, 0); WhDefferedList.Execute(); characterModel.EmulateDraw(false); return(characterModel); }
public Character Build(WowVrcFile file, bool ignoreItemsAndMount = false) { WowObject characterWowObject; var opts = file.GetOpts(); if (opts != null) { if (ignoreItemsAndMount) { opts = opts.GetCopy(); opts.items = null; opts.mount = null; } characterWowObject = _exporter.LoadCharacter(WhViewerOptions.FromJson(opts)); } else { var manualHeader = file.GetManualHeader(); if (manualHeader == null) { throw new System.InvalidOperationException(); } characterWowObject = _exporter.LoadCharacter(manualHeader.Race, manualHeader.Gender, ignoreItemsAndMount ? null : manualHeader.ItemIds); } // ToDo: грузить все итемы тоже. в viseme editor оно использоваться не будет так как будет передаваться ignoreItems = true, но возможно где-то понадобится var res = new Character() { WowObject = characterWowObject, Root = CreateCharacterGameObjects(characterWowObject) }; return(res); }
public static bool ExportToFbx(this WowVrcFile file, string exportDirectory, bool prepareForVRChat, float scale, out string warnings) { var exporter = new WowModelExporter(); WowObject characterWowObject; var opts = file.GetOpts(); if (opts != null) { characterWowObject = exporter.LoadCharacter(WhViewerOptions.FromJson(opts), scale); } else { var manualHeader = file.GetManualHeader(); if (manualHeader == null) { throw new System.InvalidOperationException(); } characterWowObject = exporter.LoadCharacter(manualHeader.Race, manualHeader.Gender, manualHeader.ItemIds, scale); } // ToDo: после запекания идет привязка на текущие индексы вершин. Если вершины будут перестроены, надо тут тоже обновить индексы var bakedBlendshapes = new List <BlendShapeUtility.BakedBlendshape>(); if (file.Blendshapes != null) { foreach (var blendshape in file.Blendshapes) { if (blendshape.Bones.Length > 0) { if (blendshape.Name == WowVrcFileData.BlendshapeData.basicBlendshapeName) { var basicBakedBlendshape = BlendShapeUtility.BakeBlendShape(characterWowObject.GlobalPosition, characterWowObject.MainMesh.Vertices, characterWowObject.Bones, blendshape.Bones, scale); foreach (var basicBakedBlendshapeElement in basicBakedBlendshape) { characterWowObject.MainMesh.Vertices[basicBakedBlendshapeElement.Key].Position = new Vec3(basicBakedBlendshapeElement.Value.Position.X, basicBakedBlendshapeElement.Value.Position.Y, basicBakedBlendshapeElement.Value.Position.Z); characterWowObject.MainMesh.Vertices[basicBakedBlendshapeElement.Key].Normal = new Vec3(basicBakedBlendshapeElement.Value.Normal.X, basicBakedBlendshapeElement.Value.Normal.Y, basicBakedBlendshapeElement.Value.Normal.Z); } } else { bakedBlendshapes.Add(new BlendShapeUtility.BakedBlendshape { BlendshapeName = blendshape.Name, Changes = BlendShapeUtility.BakeBlendShape(characterWowObject.GlobalPosition, characterWowObject.MainMesh.Vertices, characterWowObject.Bones, blendshape.Bones, scale) }); } } } } if (prepareForVRChat) { warnings = PrepareForVRChatUtility.PrepareObject(characterWowObject, bakedBlendshapes, scale, true, true, true, true, true, true); } else { warnings = null; } var fbxExporter = new Exporter(); return(fbxExporter.ExportWowObject(characterWowObject, bakedBlendshapes, exportDirectory, false)); }
public WowObject LoadCharacter(WhViewerOptions opts, float scale = 1f) { var whCharacterModel = LoadWhCharacterModel(opts); return(new WowObjectBuilder(scale).BuildFromCharacterWhModel(whCharacterModel)); }