예제 #1
0
        private static ModelRoot RawTargetsToGLTF(List <RawMeshContainer> meshes, List <RawTargetContainer[]> expTargets, string[] names, RawArmature rig)
        {
            var model = ModelRoot.CreateModel();
            var mat   = model.CreateMaterial("Default");

            mat.WithPBRMetallicRoughness().WithDefault();
            mat.DoubleSided = true;
            var skins = new List <Skin>();

            if (rig != null)
            {
                var skin = model.CreateSkin();
                skin.BindJoints(RIG.ExportNodes(ref model, rig).Values.ToArray());
                skins.Add(skin);
            }

            var ms     = new MemoryStream();
            var bw     = new BinaryWriter(ms);
            var mIndex = -1;

            foreach (var mesh in meshes)
            {
                ++mIndex;
                for (var i = 0; i < mesh.positions.Length; i++)
                {
                    bw.Write(mesh.positions[i].X);
                    bw.Write(mesh.positions[i].Y);
                    bw.Write(mesh.positions[i].Z);
                }
                for (var i = 0; i < mesh.normals.Length; i++)
                {
                    bw.Write(mesh.normals[i].X);
                    bw.Write(mesh.normals[i].Y);
                    bw.Write(mesh.normals[i].Z);
                }
                for (var i = 0; i < mesh.tangents.Length; i++)
                {
                    bw.Write(mesh.tangents[i].X);
                    bw.Write(mesh.tangents[i].Y);
                    bw.Write(mesh.tangents[i].Z);
                    bw.Write(mesh.tangents[i].W);
                }
                for (var i = 0; i < mesh.colors0.Length; i++)
                {
                    bw.Write(mesh.colors0[i].X);
                    bw.Write(mesh.colors0[i].Y);
                    bw.Write(mesh.colors0[i].Z);
                    bw.Write(mesh.colors0[i].W);
                }
                for (var i = 0; i < mesh.colors1.Length; i++)
                {
                    bw.Write(mesh.colors1[i].X);
                    bw.Write(mesh.colors1[i].Y);
                    bw.Write(mesh.colors1[i].Z);
                    bw.Write(mesh.colors1[i].W);
                }
                for (var i = 0; i < mesh.texCoords0.Length; i++)
                {
                    bw.Write(mesh.texCoords0[i].X);
                    bw.Write(mesh.texCoords0[i].Y);
                }
                for (var i = 0; i < mesh.texCoords1.Length; i++)
                {
                    bw.Write(mesh.texCoords1[i].X);
                    bw.Write(mesh.texCoords1[i].Y);
                }

                if (mesh.weightCount > 0)
                {
                    if (rig != null)
                    {
                        for (var i = 0; i < mesh.positions.Length; i++)
                        {
                            bw.Write(mesh.boneindices[i, 0]);
                            bw.Write(mesh.boneindices[i, 1]);
                            bw.Write(mesh.boneindices[i, 2]);
                            bw.Write(mesh.boneindices[i, 3]);
                        }
                        for (var i = 0; i < mesh.positions.Length; i++)
                        {
                            bw.Write(mesh.weights[i, 0]);
                            bw.Write(mesh.weights[i, 1]);
                            bw.Write(mesh.weights[i, 2]);
                            bw.Write(mesh.weights[i, 3]);
                        }
                        if (mesh.weightCount > 4)
                        {
                            for (var i = 0; i < mesh.positions.Length; i++)
                            {
                                bw.Write(mesh.boneindices[i, 4]);
                                bw.Write(mesh.boneindices[i, 5]);
                                bw.Write(mesh.boneindices[i, 6]);
                                bw.Write(mesh.boneindices[i, 7]);
                            }
                            for (var i = 0; i < mesh.positions.Length; i++)
                            {
                                bw.Write(mesh.weights[i, 4]);
                                bw.Write(mesh.weights[i, 5]);
                                bw.Write(mesh.weights[i, 6]);
                                bw.Write(mesh.weights[i, 7]);
                            }
                        }
                    }
                }
                for (var i = 0; i < mesh.indices.Length; i += 3)
                {
                    bw.Write(Convert.ToUInt16(mesh.indices[i + 1]));
                    bw.Write(Convert.ToUInt16(mesh.indices[i + 0]));
                    bw.Write(Convert.ToUInt16(mesh.indices[i + 2]));
                }
                for (var i = 0; i < expTargets.Count; i++)
                {
                    var mappings = expTargets[i][mIndex].vertexMapping.ToList();
                    for (ushort e = 0; e < mesh.positions.Length; e++)
                    {
                        if (mappings.Contains(e))
                        {
                            var idx = mappings.IndexOf(e);
                            bw.Write(expTargets[i][mIndex].vertexDelta[idx].X);
                            bw.Write(expTargets[i][mIndex].vertexDelta[idx].Y);
                            bw.Write(expTargets[i][mIndex].vertexDelta[idx].Z);
                        }
                        else
                        {
                            bw.Write(0f);
                            bw.Write(0f);
                            bw.Write(0f);
                        }
                    }
                    for (ushort e = 0; e < mesh.normals.Length; e++)
                    {
                        if (mappings.Contains(e))
                        {
                            var idx = mappings.IndexOf(e);
                            bw.Write(expTargets[i][mIndex].normalDelta[idx].X);
                            bw.Write(expTargets[i][mIndex].normalDelta[idx].Y);
                            bw.Write(expTargets[i][mIndex].normalDelta[idx].Z);
                        }
                        else
                        {
                            bw.Write(0f);
                            bw.Write(0f);
                            bw.Write(0f);
                        }
                    }
                    for (ushort e = 0; e < mesh.tangents.Length; e++)
                    {
                        if (mappings.Contains(e))
                        {
                            var idx = mappings.IndexOf(e);
                            bw.Write(expTargets[i][mIndex].tangentDelta[idx].X);
                            bw.Write(expTargets[i][mIndex].tangentDelta[idx].Y);
                            bw.Write(expTargets[i][mIndex].tangentDelta[idx].Z);
                        }
                        else
                        {
                            bw.Write(0f);
                            bw.Write(0f);
                            bw.Write(0f);
                        }
                    }
                }
            }
            var buffer         = model.UseBuffer(ms.ToArray());
            var BuffViewoffset = 0;

            foreach (var mesh in meshes)
            {
                var mes  = model.CreateMesh(mesh.name);
                var prim = mes.CreatePrimitive();
                prim.Material = mat;
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.positions.Length * 12);
                    acc.SetData(buff, 0, mesh.positions.Length, DimensionType.VEC3, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("POSITION", acc);
                    BuffViewoffset += mesh.positions.Length * 12;
                }
                if (mesh.normals.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.normals.Length * 12);
                    acc.SetData(buff, 0, mesh.normals.Length, DimensionType.VEC3, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("NORMAL", acc);
                    BuffViewoffset += mesh.normals.Length * 12;
                }
                if (mesh.tangents.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.tangents.Length * 16);
                    acc.SetData(buff, 0, mesh.tangents.Length, DimensionType.VEC4, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("TANGENT", acc);
                    BuffViewoffset += mesh.tangents.Length * 16;
                }
                if (mesh.colors0.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.colors0.Length * 16);
                    acc.SetData(buff, 0, mesh.colors0.Length, DimensionType.VEC4, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("COLOR_0", acc);
                    BuffViewoffset += mesh.colors0.Length * 16;
                }
                if (mesh.colors1.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.colors1.Length * 16);
                    acc.SetData(buff, 0, mesh.colors1.Length, DimensionType.VEC4, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("COLOR_1", acc);
                    BuffViewoffset += mesh.colors1.Length * 16;
                }
                if (mesh.texCoords0.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.texCoords0.Length * 8);
                    acc.SetData(buff, 0, mesh.texCoords0.Length, DimensionType.VEC2, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("TEXCOORD_0", acc);
                    BuffViewoffset += mesh.texCoords0.Length * 8;
                }
                if (mesh.texCoords1.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.texCoords1.Length * 8);
                    acc.SetData(buff, 0, mesh.texCoords1.Length, DimensionType.VEC2, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("TEXCOORD_1", acc);
                    BuffViewoffset += mesh.texCoords1.Length * 8;
                }
                if (mesh.weightCount > 0)
                {
                    if (rig != null)
                    {
                        {
                            var acc  = model.CreateAccessor();
                            var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.positions.Length * 8);
                            acc.SetData(buff, 0, mesh.positions.Length, DimensionType.VEC4, EncodingType.UNSIGNED_SHORT, false);
                            prim.SetVertexAccessor("JOINTS_0", acc);
                            BuffViewoffset += mesh.positions.Length * 8;
                        }
                        {
                            var acc  = model.CreateAccessor();
                            var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.positions.Length * 16);
                            acc.SetData(buff, 0, mesh.positions.Length, DimensionType.VEC4, EncodingType.FLOAT, false);
                            prim.SetVertexAccessor("WEIGHTS_0", acc);
                            BuffViewoffset += mesh.positions.Length * 16;
                        }
                        if (mesh.weightCount > 4)
                        {
                            {
                                var acc  = model.CreateAccessor();
                                var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.positions.Length * 8);
                                acc.SetData(buff, 0, mesh.positions.Length, DimensionType.VEC4, EncodingType.UNSIGNED_SHORT, false);
                                prim.SetVertexAccessor("JOINTS_1", acc);
                                BuffViewoffset += mesh.positions.Length * 8;
                            }
                            {
                                var acc  = model.CreateAccessor();
                                var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.positions.Length * 16);
                                acc.SetData(buff, 0, mesh.positions.Length, DimensionType.VEC4, EncodingType.FLOAT, false);
                                prim.SetVertexAccessor("WEIGHTS_1", acc);
                                BuffViewoffset += mesh.positions.Length * 16;
                            }
                        }
                    }
                }
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.indices.Length * 2);
                    acc.SetData(buff, 0, mesh.indices.Length, DimensionType.SCALAR, EncodingType.UNSIGNED_SHORT, false);
                    prim.SetIndexAccessor(acc);
                    BuffViewoffset += mesh.indices.Length * 2;
                }
                var nod = model.UseScene(0).CreateNode(mesh.name);
                nod.Mesh = mes;
                if (rig != null && mesh.weightCount > 0)
                {
                    nod.Skin = skins[0];
                }

                var obj = new { targetNames = names }; // anonymous variable/obj
                mes.Extras = SharpGLTF.IO.JsonContent.Serialize(obj);

                for (var i = 0; i < expTargets.Count; i++)
                {
                    var dict = new Dictionary <string, Accessor>();
                    {
                        var acc  = model.CreateAccessor();
                        var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.positions.Length * 12);
                        acc.SetData(buff, 0, mesh.positions.Length, DimensionType.VEC3, EncodingType.FLOAT, false);
                        dict.Add("POSITION", acc);
                        BuffViewoffset += mesh.positions.Length * 12;
                    }
                    if (mesh.normals.Length > 0)
                    {
                        var acc  = model.CreateAccessor();
                        var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.normals.Length * 12);
                        acc.SetData(buff, 0, mesh.normals.Length, DimensionType.VEC3, EncodingType.FLOAT, false);
                        dict.Add("NORMAL", acc);
                        BuffViewoffset += mesh.normals.Length * 12;
                    }
                    if (mesh.tangents.Length > 0)
                    {
                        var acc  = model.CreateAccessor();
                        var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.tangents.Length * 12);
                        acc.SetData(buff, 0, mesh.tangents.Length, DimensionType.VEC3, EncodingType.FLOAT, false);
                        dict.Add("TANGENT", acc);
                        BuffViewoffset += mesh.tangents.Length * 12;
                    }
                    prim.SetMorphTargetAccessors(i, dict);
                }
            }
            model.UseScene(0).Name = "Scene";
            model.DefaultScene     = model.UseScene(0);
            model.MergeBuffers();
            return(model);
        }
예제 #2
0
        public static ModelRoot RawMeshesToGLTF(List <RawMeshContainer> meshes, RawArmature Rig)
        {
            var model = ModelRoot.CreateModel();
            var mat   = model.CreateMaterial("Default");

            mat.WithPBRMetallicRoughness().WithDefault();
            mat.DoubleSided = true;
            List <Skin> skins = new List <Skin>();

            if (Rig != null)
            {
                var skin = model.CreateSkin();
                skin.BindJoints(RIG.ExportNodes(ref model, Rig).Values.ToArray());
                skins.Add(skin);
            }

            var ms = new MemoryStream();
            var bw = new BinaryWriter(ms);

            foreach (var mesh in meshes)
            {
                for (int i = 0; i < mesh.vertices.Length; i++)
                {
                    bw.Write(mesh.vertices[i].X);
                    bw.Write(mesh.vertices[i].Y);
                    bw.Write(mesh.vertices[i].Z);
                }
                for (int i = 0; i < mesh.normals.Length; i++)
                {
                    bw.Write(mesh.normals[i].X);
                    bw.Write(mesh.normals[i].Y);
                    bw.Write(mesh.normals[i].Z);
                }
                for (int i = 0; i < mesh.tangents.Length; i++)
                {
                    bw.Write(mesh.tangents[i].X);
                    bw.Write(mesh.tangents[i].Y);
                    bw.Write(mesh.tangents[i].Z);
                    bw.Write(mesh.tangents[i].W);
                }
                for (int i = 0; i < mesh.colors.Length; i++)
                {
                    bw.Write(mesh.colors[i].X);
                    bw.Write(mesh.colors[i].Y);
                    bw.Write(mesh.colors[i].Z);
                    bw.Write(mesh.colors[i].W);
                }
                for (int i = 0; i < mesh.tx0coords.Length; i++)
                {
                    bw.Write(mesh.tx0coords[i].X);
                    bw.Write(mesh.tx0coords[i].Y);
                }
                for (int i = 0; i < mesh.tx1coords.Length; i++)
                {
                    bw.Write(mesh.tx1coords[i].X);
                    bw.Write(mesh.tx1coords[i].Y);
                }

                if (mesh.weightcount > 0)
                {
                    if (Rig != null)
                    {
                        for (int i = 0; i < mesh.vertices.Length; i++)
                        {
                            bw.Write(mesh.boneindices[i, 0]);
                            bw.Write(mesh.boneindices[i, 1]);
                            bw.Write(mesh.boneindices[i, 2]);
                            bw.Write(mesh.boneindices[i, 3]);
                        }
                        for (int i = 0; i < mesh.vertices.Length; i++)
                        {
                            bw.Write(mesh.weights[i, 0]);
                            bw.Write(mesh.weights[i, 1]);
                            bw.Write(mesh.weights[i, 2]);
                            bw.Write(mesh.weights[i, 3]);
                        }
                        if (mesh.weightcount > 4)
                        {
                            for (int i = 0; i < mesh.vertices.Length; i++)
                            {
                                bw.Write(mesh.boneindices[i, 4]);
                                bw.Write(mesh.boneindices[i, 5]);
                                bw.Write(mesh.boneindices[i, 6]);
                                bw.Write(mesh.boneindices[i, 7]);
                            }
                            for (int i = 0; i < mesh.vertices.Length; i++)
                            {
                                bw.Write(mesh.weights[i, 4]);
                                bw.Write(mesh.weights[i, 5]);
                                bw.Write(mesh.weights[i, 6]);
                                bw.Write(mesh.weights[i, 7]);
                            }
                        }
                    }
                }
                for (int i = 0; i < mesh.indices.Length; i += 3)
                {
                    bw.Write(Convert.ToUInt16(mesh.indices[i + 1]));
                    bw.Write(Convert.ToUInt16(mesh.indices[i + 0]));
                    bw.Write(Convert.ToUInt16(mesh.indices[i + 2]));
                }
                if (mesh.extraExist)
                {
                    for (int i = 0; i < mesh.vertices.Length; i++)
                    {
                        bw.Write(mesh.extradata[i].X);
                        bw.Write(mesh.extradata[i].Y);
                        bw.Write(mesh.extradata[i].Z);
                    }
                }
            }
            var buffer         = model.UseBuffer(ms.ToArray());
            int BuffViewoffset = 0;

            foreach (var mesh in meshes)
            {
                var mes  = model.CreateMesh(mesh.name);
                var prim = mes.CreatePrimitive();
                prim.Material = mat;
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.vertices.Length * 12);
                    acc.SetData(buff, 0, mesh.vertices.Length, DimensionType.VEC3, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("POSITION", acc);
                    BuffViewoffset += mesh.vertices.Length * 12;
                }
                if (mesh.normals.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.normals.Length * 12);
                    acc.SetData(buff, 0, mesh.normals.Length, DimensionType.VEC3, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("NORMAL", acc);
                    BuffViewoffset += mesh.normals.Length * 12;
                }
                if (mesh.tangents.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.tangents.Length * 16);
                    acc.SetData(buff, 0, mesh.tangents.Length, DimensionType.VEC4, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("TANGENT", acc);
                    BuffViewoffset += mesh.tangents.Length * 16;
                }
                if (mesh.colors.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.colors.Length * 16);
                    acc.SetData(buff, 0, mesh.colors.Length, DimensionType.VEC4, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("COLOR_0", acc);
                    BuffViewoffset += mesh.colors.Length * 16;
                }
                if (mesh.tx0coords.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.tx0coords.Length * 8);
                    acc.SetData(buff, 0, mesh.tx0coords.Length, DimensionType.VEC2, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("TEXCOORD_0", acc);
                    BuffViewoffset += mesh.tx0coords.Length * 8;
                }
                if (mesh.tx1coords.Length > 0)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.tx1coords.Length * 8);
                    acc.SetData(buff, 0, mesh.tx1coords.Length, DimensionType.VEC2, EncodingType.FLOAT, false);
                    prim.SetVertexAccessor("TEXCOORD_1", acc);
                    BuffViewoffset += mesh.tx1coords.Length * 8;
                }
                if (mesh.weightcount > 0)
                {
                    if (Rig != null)
                    {
                        {
                            var acc  = model.CreateAccessor();
                            var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.vertices.Length * 8);
                            acc.SetData(buff, 0, mesh.vertices.Length, DimensionType.VEC4, EncodingType.UNSIGNED_SHORT, false);
                            prim.SetVertexAccessor("JOINTS_0", acc);
                            BuffViewoffset += mesh.vertices.Length * 8;
                        }
                        {
                            var acc  = model.CreateAccessor();
                            var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.vertices.Length * 16);
                            acc.SetData(buff, 0, mesh.vertices.Length, DimensionType.VEC4, EncodingType.FLOAT, false);
                            prim.SetVertexAccessor("WEIGHTS_0", acc);
                            BuffViewoffset += mesh.vertices.Length * 16;
                        }
                        if (mesh.weightcount > 4)
                        {
                            {
                                var acc  = model.CreateAccessor();
                                var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.vertices.Length * 8);
                                acc.SetData(buff, 0, mesh.vertices.Length, DimensionType.VEC4, EncodingType.UNSIGNED_SHORT, false);
                                prim.SetVertexAccessor("JOINTS_1", acc);
                                BuffViewoffset += mesh.vertices.Length * 8;
                            }
                            {
                                var acc  = model.CreateAccessor();
                                var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.vertices.Length * 16);
                                acc.SetData(buff, 0, mesh.vertices.Length, DimensionType.VEC4, EncodingType.FLOAT, false);
                                prim.SetVertexAccessor("WEIGHTS_1", acc);
                                BuffViewoffset += mesh.vertices.Length * 16;
                            }
                        }
                    }
                }
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.indices.Length * 2);
                    acc.SetData(buff, 0, mesh.indices.Length, DimensionType.SCALAR, EncodingType.UNSIGNED_SHORT, false);
                    prim.SetIndexAccessor(acc);
                    BuffViewoffset += mesh.indices.Length * 2;
                }
                var nod = model.UseScene(0).CreateNode(mesh.name);
                nod.Mesh = mes;
                if (Rig != null && mesh.weightcount > 0)
                {
                    nod.Skin = skins[0];
                }

                if (mesh.extraExist)
                {
                    string[] arr = { "GarmentSupport" };
                    var      obj = new { appNames = mesh.appNames, materialNames = mesh.materialNames, targetNames = arr };
                    mes.Extras = SharpGLTF.IO.JsonContent.Serialize(obj);
                }
                else
                {
                    var obj = new { appNames = mesh.appNames, materialNames = mesh.materialNames };
                    mes.Extras = SharpGLTF.IO.JsonContent.Serialize(obj);
                }
                if (mesh.extraExist)
                {
                    var acc  = model.CreateAccessor();
                    var buff = model.UseBufferView(buffer, BuffViewoffset, mesh.extradata.Length * 12);
                    acc.SetData(buff, 0, mesh.extradata.Length, DimensionType.VEC3, EncodingType.FLOAT, false);
                    var dict = new Dictionary <string, Accessor>();
                    dict.Add("POSITION", acc);
                    prim.SetMorphTargetAccessors(0, dict);
                    BuffViewoffset += mesh.extradata.Length * 12;
                }
            }
            model.UseScene(0).Name = "Scene";
            model.DefaultScene     = model.UseScene(0);
            model.MergeBuffers();
            return(model);
        }
예제 #3
0
        public bool ExportAnim(Stream animStream, List <Archive> archives, FileInfo outfile, bool isGLBinary = true)
        {
            var cr2w = _wolvenkitFileService.TryReadRED4File(animStream);

            if (!cr2w.Chunks.Select(_ => _.Data).OfType <animAnimSet>().Any())
            {
                return(false);
            }
            var blob = cr2w.Chunks.Select(_ => _.Data).OfType <animAnimSet>().First();

            List <MemoryStream> animDataBuffers = new List <MemoryStream>();

            foreach (var chk in blob.AnimationDataChunks)
            {
                UInt16 bufferIdx = chk.Buffer.Buffer.Value;
                var    b         = cr2w.Buffers[bufferIdx - 1];
                animStream.Seek(b.Offset, SeekOrigin.Begin);
                var ms = new MemoryStream();
                animStream.DecompressAndCopySegment(ms, b.DiskSize, b.MemSize);
                animDataBuffers.Add(ms);
            }
            RawArmature Rig = null;

            {
                ulong hash = FNV1A64HashAlgorithm.HashString(blob.Rig.DepotPath);
                foreach (Archive ar in archives)
                {
                    if (ar.Files.ContainsKey(hash))
                    {
                        var ms = new MemoryStream();
                        ModTools.ExtractSingleToStream(ar, hash, ms);
                        Rig = new RIG(_wolvenkitFileService).ProcessRig(ms);
                        break;
                    }
                }
            }
            if (Rig.BoneCount < 1)
            {
                return(false);
            }
            var model = ModelRoot.CreateModel();
            var skin  = model.CreateSkin();

            skin.BindJoints(RIG.ExportNodes(ref model, Rig).Values.ToArray());

            for (int i = 0; i < blob.Animations.Count; i++)
            {
                var setEntry    = (blob.Animations[i].GetReference().Data as animAnimSetEntry);
                var animAnimDes = (setEntry.Animation.GetReference().Data as animAnimation);
                if (animAnimDes.AnimationType.Value != Enums.animAnimationType.Normal)
                {
                    continue;
                }
                switch (animAnimDes.AnimBuffer.GetReference().REDType)
                {
                case "animAnimationBufferSimd":
                {
                    var animBuff  = (animAnimDes.AnimBuffer.GetReference().Data as animAnimationBufferSimd);
                    var bufferIdx = animBuff.DefferedBuffer.Buffer.Value;
                    var b         = cr2w.Buffers[bufferIdx - 1];
                    animStream.Seek(b.Offset, SeekOrigin.Begin);
                    var defferedBuffer = new MemoryStream();
                    animStream.DecompressAndCopySegment(defferedBuffer, b.DiskSize, b.MemSize);
                    SIMD.AddAnimationSIMD(ref model, animBuff, animAnimDes.Name.Value, defferedBuffer);
                }
                break;

                case "animAnimationBufferCompressed":
                {
                    var    animBuff = (animAnimDes.AnimBuffer.GetReference().Data as animAnimationBufferCompressed);
                    var    dataAddr = animBuff.DataAddress;
                    Byte[] bytes    = new Byte[dataAddr.ZeInBytes.Value];
                    animDataBuffers[(int)dataAddr.UnkIndex.Value].Seek(dataAddr.FsetInBytes.Value, SeekOrigin.Begin);
                    animDataBuffers[(int)dataAddr.UnkIndex.Value].Read(bytes, 0, (int)dataAddr.ZeInBytes.Value);
                    var defferedBuffer = new MemoryStream(bytes);
                    SPLINE.AddAnimationSpline(ref model, animBuff, animAnimDes.Name.Value, defferedBuffer);
                }
                break;

                default:
                    break;
                }
            }
            if (isGLBinary)
            {
                model.SaveGLB(outfile.FullName);
            }
            else
            {
                model.SaveGLTF(outfile.FullName);
            }

            return(true);
        }
예제 #4
0
        public bool ExportAnim(Stream animStream, List <Archive> archives, FileInfo outfile, bool isGLBinary = true)
        {
            var cr2w = _wolvenkitFileService.ReadRed4File(animStream);

            if (cr2w == null || cr2w.RootChunk is not animAnimSet blob)
            {
                return(false);
            }

            var animDataBuffers = new List <MemoryStream>();

            foreach (var chk in blob.AnimationDataChunks)
            {
                var ms = new MemoryStream();
                ms.Write(chk.Buffer.Buffer.GetBytes());

                animDataBuffers.Add(ms);
            }

            var Rig  = new RawArmature();
            var hash = FNV1A64HashAlgorithm.HashString(blob.Rig.DepotPath);

            foreach (var ar in archives)
            {
                if (ar.Files.ContainsKey(hash))
                {
                    var ms = new MemoryStream();
                    ModTools.ExtractSingleToStream(ar, hash, ms);
                    Rig = RIG.ProcessRig(_wolvenkitFileService.ReadRed4File(ms));
                    break;
                }
            }

            if (Rig is null)
            {
                return(false);
            }

            if (Rig.BoneCount < 1)
            {
                return(false);
            }

            var model = ModelRoot.CreateModel();
            var skin  = model.CreateSkin();

            skin.BindJoints(RIG.ExportNodes(ref model, Rig).Values.ToArray());

            for (var i = 0; i < blob.Animations.Count; i++)
            {
                var setEntry    = blob.Animations[i].Chunk;
                var animAnimDes = setEntry.Animation.Chunk;
                if (animAnimDes.AnimationType.Value != Enums.animAnimationType.Normal)
                {
                    continue;
                }

                if (animAnimDes.AnimBuffer.Chunk is animAnimationBufferSimd)
                {
                    var          animBuff = (animAnimDes.AnimBuffer.Chunk as animAnimationBufferSimd);
                    MemoryStream defferedBuffer;
                    if (animBuff.InplaceCompressedBuffer != null)
                    {
                        defferedBuffer = new MemoryStream(animBuff.InplaceCompressedBuffer.Buffer.GetBytes());
                    }
                    else
                    {
                        defferedBuffer = new MemoryStream(animBuff.DefferedBuffer.Buffer.GetBytes());
                    }
                    defferedBuffer.Seek(0, SeekOrigin.Begin);
                    SIMD.AddAnimationSIMD(ref model, animBuff, animAnimDes.Name, defferedBuffer, animAnimDes);
                }
                else if (animAnimDes.AnimBuffer.Chunk is animAnimationBufferCompressed)
                {
                    var animBuff       = (animAnimDes.AnimBuffer.Chunk as animAnimationBufferCompressed);
                    var defferedBuffer = new MemoryStream();
                    if (animBuff.InplaceCompressedBuffer != null)
                    {
                        defferedBuffer = new MemoryStream(animBuff.InplaceCompressedBuffer.Buffer.GetBytes());
                    }
                    else if (animBuff.DataAddress != null)
                    {
                        var dataAddr = animBuff.DataAddress;
                        var bytes    = new byte[dataAddr.ZeInBytes];
                        animDataBuffers[(int)((uint)dataAddr.UnkIndex)].Seek(dataAddr.FsetInBytes, SeekOrigin.Begin);
                        animDataBuffers[(int)((uint)dataAddr.UnkIndex)].Read(bytes, 0, (int)((uint)dataAddr.ZeInBytes));
                        defferedBuffer = new MemoryStream(bytes);
                    }
                    else if (animBuff.DefferedBuffer.Buffer.MemSize > 0)
                    {
                        defferedBuffer.Write(animBuff.DefferedBuffer.Buffer.GetBytes());
                    }
                    defferedBuffer.Seek(0, SeekOrigin.Begin);
                    SPLINE.AddAnimationSpline(ref model, animBuff, animAnimDes.Name, defferedBuffer, animAnimDes);
                }
            }
            if (isGLBinary)
            {
                model.SaveGLB(outfile.FullName);
            }
            else
            {
                model.SaveGLTF(outfile.FullName);
            }

            return(true);
        }