Exemplo n.º 1
0
        public static VrmProtobuf.Image ToGltf(this Image src, Vrm10Storage storage)
        {
            var viewIndex = storage.AppendToBuffer(0, src.Bytes, 1);
            var gltf      = storage.Gltf;

            return(new VrmProtobuf.Image
            {
                Name = src.Name,
                MimeType = src.MimeType,
                BufferView = viewIndex,
            });
        }
Exemplo n.º 2
0
        public static int AddViewTo(this BufferAccessor self,
                                    Vrm10Storage storage, int bufferIndex,
                                    int offset = 0, int count = 0)
        {
            var stride = self.Stride;

            if (count == 0)
            {
                count = self.Count;
            }
            var slice = self.Bytes.Slice(offset * stride, count * stride);

            return(storage.AppendToBuffer(bufferIndex, slice, stride));
        }
Exemplo n.º 3
0
        public static int AddAccessorTo(this BufferAccessor self,
                                        Vrm10Storage storage, int bufferIndex,
                                        // GltfBufferTargetType targetType,
                                        bool useSparse,
                                        Action <Memory <byte>, VrmProtobuf.Accessor> minMax = null,
                                        int offset = 0, int count = 0)
        {
            if (self.ComponentType == AccessorValueType.FLOAT &&
                self.AccessorType == AccessorVectorType.VEC3
                )
            {
                var values = self.GetSpan <Vector3>();
                // 巨大ポリゴンのモデル対策にValueTupleの型をushort -> uint へ
                var sparseValuesWithIndex = new List <ValueTuple <int, Vector3> >();
                for (int i = 0; i < values.Length; ++i)
                {
                    var v = values[i];
                    if (v != Vector3.Zero)
                    {
                        sparseValuesWithIndex.Add((i, v));
                    }
                }

                //var status = $"{sparseIndices.Count * 14}/{values.Length * 12}";
                if (useSparse &&
                    sparseValuesWithIndex.Count > 0 && // avoid empty sparse
                    sparseValuesWithIndex.Count * 16 < values.Length * 12)
                {
                    // use sparse
                    var sparseIndexBin  = new byte[sparseValuesWithIndex.Count * 4].AsMemory();
                    var sparseIndexSpan = MemoryMarshal.Cast <byte, int>(sparseIndexBin.Span);
                    var sparseValueBin  = new byte[sparseValuesWithIndex.Count * 12].AsMemory();
                    var sparseValueSpan = MemoryMarshal.Cast <byte, Vector3>(sparseValueBin.Span);

                    for (int i = 0; i < sparseValuesWithIndex.Count; ++i)
                    {
                        var(index, value)  = sparseValuesWithIndex[i];
                        sparseIndexSpan[i] = index;
                        sparseValueSpan[i] = value;
                    }

                    var sparseIndexView = storage.AppendToBuffer(bufferIndex, sparseIndexBin, 4);
                    var sparseValueView = storage.AppendToBuffer(bufferIndex, sparseValueBin, 12);

                    var accessorIndex = storage.Gltf.Accessors.Count;
                    var accessor      = new VrmProtobuf.Accessor
                    {
                        ComponentType = (int)self.ComponentType,
                        Type          = EnumUtil.Cast <VrmProtobuf.Accessor.Types.accessorType>(self.AccessorType),
                        Count         = self.Count,
                        Sparse        = new VrmProtobuf.AccessorSparse
                        {
                            Count   = sparseValuesWithIndex.Count,
                            Indices = new VrmProtobuf.AccessorSparseIndices
                            {
                                ComponentType = (int)AccessorValueType.UNSIGNED_INT,
                                BufferView    = sparseIndexView,
                            },
                            Values = new VrmProtobuf.AccessorSparseValues
                            {
                                BufferView = sparseValueView,
                            },
                        }
                    };
                    if (minMax != null)
                    {
                        minMax(sparseValueBin, accessor);
                    }
                    storage.Gltf.Accessors.Add(accessor);
                    return(accessorIndex);
                }
            }

            var viewIndex = self.AddViewTo(storage, bufferIndex, offset, count);

            return(self.AddAccessorTo(storage, viewIndex, minMax, 0, count));
        }