Example #1
0
        public static VertexBuffer FromGltf(this VrmProtobuf.target target, Vrm10Storage storage)
        {
            var b = new VertexBuffer();

            storage.CreateBufferAccessorAndAdd(target.POSITION, b, VertexBuffer.PositionKey);
            storage.CreateBufferAccessorAndAdd(target.NORMAL, b, VertexBuffer.NormalKey);
            storage.CreateBufferAccessorAndAdd(target.TANGENT, b, VertexBuffer.TangentKey);
            return(b);
        }
Example #2
0
        static void ExportMesh(this Mesh mesh, List <Material> materials, Vrm10Storage storage, VrmProtobuf.Mesh gltfMesh, ExportArgs option)
        {
            //
            // primitive share vertex buffer
            //
            var attributeAccessorIndexMap = mesh.VertexBuffer
                                            .ToDictionary(
                kv => kv.Key,
                kv => kv.Value.AddAccessorTo(
                    storage, 0, option.sparse,
                    kv.Key == VertexBuffer.PositionKey ? (Action <Memory <byte>, VrmProtobuf.Accessor>)Vec3MinMax : null
                    )
                );

            List <Dictionary <string, int> > morphTargetAccessorIndexMapList = null;

            if (mesh.MorphTargets.Any())
            {
                morphTargetAccessorIndexMapList = new List <Dictionary <string, int> >();
                foreach (var morphTarget in mesh.MorphTargets)
                {
                    var dict = new Dictionary <string, int>();

                    foreach (var kv in morphTarget.VertexBuffer)
                    {
                        if (option.removeTangent && kv.Key == VertexBuffer.TangentKey)
                        {
                            // remove tangent
                            continue;
                        }
                        if (option.removeMorphNormal && kv.Key == VertexBuffer.NormalKey)
                        {
                            // normal normal
                            continue;
                        }
                        if (kv.Value.Count != mesh.VertexBuffer.Count)
                        {
                            throw new Exception("inavlid data");
                        }
                        var accessorIndex = kv.Value.AddAccessorTo(storage, 0,
                                                                   option.sparse,
                                                                   kv.Key == VertexBuffer.PositionKey ? (Action <Memory <byte>, VrmProtobuf.Accessor>)Vec3MinMax : null);
                        dict.Add(kv.Key, accessorIndex);
                    }

                    morphTargetAccessorIndexMapList.Add(dict);
                }
            }

            var drawCountOffset = 0;

            foreach (var y in mesh.Submeshes)
            {
                // index
                // slide index buffer accessor
                var indicesAccessorIndex = ExportIndices(storage, mesh.IndexBuffer, drawCountOffset, y.DrawCount, option);
                drawCountOffset += y.DrawCount;

                var prim = new VrmProtobuf.MeshPrimitive
                {
                    Mode     = (int)mesh.Topology,
                    Material = materials.IndexOfNullable(y.Material),
                    Indices  = indicesAccessorIndex,
                };
                gltfMesh.Primitives.Add(prim);

                // attribute
                foreach (var kv in mesh.VertexBuffer)
                {
                    var attributeAccessorIndex = attributeAccessorIndexMap[kv.Key];
                    prim.Attributes.Add(kv.Key, attributeAccessorIndex);
                }

                // morph target
                if (mesh.MorphTargets.Any())
                {
                    foreach (var(t, accessorIndexMap) in
                             Enumerable.Zip(mesh.MorphTargets, morphTargetAccessorIndexMapList, (t, v) => (t, v)))
                    {
                        var target = new VrmProtobuf.target();
                        prim.Targets.Add(target);

                        foreach (var kv in t.VertexBuffer)
                        {
                            if (!accessorIndexMap.TryGetValue(kv.Key, out int targetAccessorIndex))
                            {
                                continue;
                            }
                            switch (kv.Key)
                            {
                            case VertexBuffer.PositionKey:
                                target.POSITION = targetAccessorIndex;
                                break;

                            case VertexBuffer.NormalKey:
                                target.NORMAL = targetAccessorIndex;
                                break;

                            case VertexBuffer.TangentKey:
                                target.TANGENT = targetAccessorIndex;
                                break;

                            default:
                                throw new NotImplementedException();
                            }
                        }
                    }

                    if (mesh.MorphTargets.Any())
                    {
                        prim.Extras = new VrmProtobuf.MeshPrimitive.Types.Extras();
                        foreach (var name in mesh.MorphTargets.Select(z => z.Name))
                        {
                            prim.Extras.TargetNames.Add(name);
                        }
                    }
                }
            }
        }