Example #1
0
        //
        // ArraySegment<byte> を新規に確保して置き換える
        //
        public void Append(BufferAccessor a, int offset = -1)
        {
            if (AccessorType != a.AccessorType)
            {
                System.Console.WriteLine(AccessorType.ToString() + "!=" + a.AccessorType.ToString());
                throw new Exception("different AccessorType");
            }

            // UNSIGNED_SHORT <-> UNSIGNED_INT の変換を許容して処理を続行
            // 統合メッシュのprimitiveのIndexBufferが65,535(ushort.MaxValue)を超える場合や、変換前にindexBuffer.ComponetTypeがushortとuint混在する場合など
            if (ComponentType != a.ComponentType)
            {
                switch (a.ComponentType)
                {
                //ushort to uint
                case AccessorValueType.UNSIGNED_SHORT:
                {
                    var src   = SpanLike.Wrap <UInt16>(a.Bytes).Slice(0, a.Count);
                    var bytes = new byte[src.Length * 4];
                    var dst   = SpanLike.Wrap <UInt32>(new ArraySegment <byte>(bytes));
                    for (int i = 0; i < src.Length; ++i)
                    {
                        dst[i] = (uint)src[i];
                    }
                    var accessor = new BufferAccessor(new ArraySegment <byte>(bytes), AccessorValueType.UNSIGNED_INT, AccessorVectorType.SCALAR, a.Count);
                    a = accessor;

                    break;
                }

                //uint to ushort (おそらく通ることはない)
                case AccessorValueType.UNSIGNED_INT:
                {
                    var src   = SpanLike.Wrap <UInt32>(a.Bytes).Slice(0, a.Count);
                    var bytes = new byte[src.Length * 2];
                    var dst   = SpanLike.Wrap <UInt16>(new ArraySegment <byte>(bytes));
                    for (int i = 0; i < src.Length; ++i)
                    {
                        dst[i] = (ushort)src[i];
                    }
                    var accessor = new BufferAccessor(new ArraySegment <byte>(bytes), ComponentType, AccessorVectorType.SCALAR, a.Count);
                    a = accessor;
                    break;
                }

                default:
                    throw new Exception("Cannot Convert ComponentType");
                }
            }

            // 連結した新しいバッファを確保
            var oldLength = Bytes.Count;

            ToByteLength(oldLength + a.Bytes.Count);
            // 後ろにコピー
            Buffer.BlockCopy(a.Bytes.Array, a.Bytes.Offset, Bytes.Array, Bytes.Offset + oldLength, a.Bytes.Count);
            Count += a.Count;

            if (offset > 0)
            {
                // 後半にoffsetを足す
                switch (ComponentType)
                {
                case AccessorValueType.UNSIGNED_SHORT:
                {
                    var span         = SpanLike.Wrap <UInt16>(Bytes.Slice(oldLength));
                    var ushortOffset = (ushort)offset;
                    for (int i = 0; i < span.Length; ++i)
                    {
                        span[i] += ushortOffset;
                    }
                }
                break;

                case AccessorValueType.UNSIGNED_INT:
                {
                    var span       = SpanLike.Wrap <UInt32>(Bytes.Slice(oldLength));
                    var uintOffset = (uint)offset;
                    for (int i = 0; i < span.Length; ++i)
                    {
                        span[i] += uintOffset;
                    }
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }
        }