Пример #1
0
    private void UpdateChanges()
    {
        UpdateBonesToSelectedBlendshape();

        // Если сейчас выбран basic блендшейп - запекаем в _basicVertexPositions измененные вершины на основании него
        if (_selectedblendShapeName == WowVrcFileData.BlendshapeData.basicBlendshapeName)
        {
            var basicVertexChanges = BlendShapeUtility.BakeBlendShape(
                _character.WowObject.GlobalPosition,
                _character.WowObject.MainMesh.Vertices,
                _character.WowObject.Bones,
                ConvertBlendshapeBonesToFile(_blendshapeData[WowVrcFileData.BlendshapeData.basicBlendshapeName].Bones),
                1f);

            _defaultVertexPositions.CopyTo(_basicVertexPositions, 0);
            _defaultVertexNormals.CopyTo(_basicVertexNormals, 0);
            foreach (var basicVertexChange in basicVertexChanges)
            {
                _basicVertexPositions[basicVertexChange.Key] = new Vector3(basicVertexChange.Value.Position.X, basicVertexChange.Value.Position.Y, basicVertexChange.Value.Position.Z);
                _basicVertexNormals[basicVertexChange.Key]   = new Vector3(basicVertexChange.Value.Normal.X, basicVertexChange.Value.Normal.Y, basicVertexChange.Value.Normal.Z);
            }
        }
    }
        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));
        }