Exemplo n.º 1
0
        /// <summary>
        /// インデックスバッファを更新する
        /// MEMO: 出力に対するushortを考慮することをやめればかなりシンプルに書ける
        /// </summary>
        private static void UpdateIndices(MeshGroup meshGroup, int vertexCount, int indexCount, Mesh resultMesh)
        {
            Profiler.BeginSample("MeshImporterDivided.UpdateIndices");

            JobHandle jobHandle = default;

            var disposables = new List <IDisposable>();

            //
            // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_accessor_componenttype
            //
            if (vertexCount < ushort.MaxValue)
            {
                // vertex buffer への index が ushort に収まる
                var indices = new NativeArray <ushort>(indexCount, Allocator.TempJob);
                disposables.Add(indices);
                var indexOffset  = 0;
                var vertexOffset = 0;
                foreach (var mesh in meshGroup.Meshes)
                {
                    switch (mesh.IndexBuffer.ComponentType)
                    {
                    case AccessorValueType.BYTE:
                    case AccessorValueType.UNSIGNED_BYTE:
                    case AccessorValueType.FLOAT:
                        throw new NotImplementedException($"{mesh.IndexBuffer.ComponentType}");

                    case AccessorValueType.SHORT:
                    case AccessorValueType.UNSIGNED_SHORT:
                    {
                        // unsigned short -> unsigned short
                        var source = mesh.IndexBuffer.Bytes.Reinterpret <ushort>(1);
                        jobHandle = new CopyIndicesJobs.Ushort2Ushort(
                            (ushort)vertexOffset,
                            new NativeSlice <ushort>(source),
                            new NativeSlice <ushort>(indices, indexOffset, mesh.IndexBuffer.Count))
                                    .Schedule(mesh.IndexBuffer.Count, 1, jobHandle);
                        break;
                    }

                    case AccessorValueType.UNSIGNED_INT:
                    {
                        // unsigned int -> unsigned short
                        var source = mesh.IndexBuffer.Bytes.Reinterpret <uint>(1);
                        jobHandle = new CopyIndicesJobs.Uint2Ushort(
                            (ushort)vertexOffset,
                            source,
                            new NativeSlice <ushort>(indices, indexOffset, mesh.IndexBuffer.Count))
                                    .Schedule(mesh.IndexBuffer.Count, 1, jobHandle);
                        break;
                    }

                    default:
                        throw new ArgumentException($"unknown index buffer type: {mesh.IndexBuffer.ComponentType}");
                    }

                    vertexOffset += mesh.VertexBuffer.Count;
                    indexOffset  += mesh.IndexBuffer.Count;
                }

                jobHandle.Complete();

                resultMesh.SetIndexBufferParams(indexCount, IndexFormat.UInt16);
                resultMesh.SetIndexBufferData(indices, 0, 0, indexCount);
            }
            else
            {
                // vertex buffer への index が ushort を超える
                var indices = new NativeArray <uint>(indexCount, Allocator.TempJob);
                disposables.Add(indices);
                var indexOffset  = 0;
                var vertexOffset = 0;
                foreach (var mesh in meshGroup.Meshes)
                {
                    switch (mesh.IndexBuffer.ComponentType)
                    {
                    case AccessorValueType.BYTE:
                    case AccessorValueType.UNSIGNED_BYTE:
                    case AccessorValueType.FLOAT:
                        throw new NotImplementedException($"{mesh.IndexBuffer.ComponentType}");

                    case AccessorValueType.SHORT:
                    case AccessorValueType.UNSIGNED_SHORT:
                    {
                        // unsigned short -> unsigned int
                        var source = mesh.IndexBuffer.Bytes.Reinterpret <ushort>(1);
                        jobHandle = new CopyIndicesJobs.Ushort2Uint(
                            (uint)vertexOffset,
                            source,
                            new NativeSlice <uint>(indices, indexOffset, mesh.IndexBuffer.Count))
                                    .Schedule(mesh.IndexBuffer.Count, 1, jobHandle);
                        break;
                    }

                    case AccessorValueType.UNSIGNED_INT:
                    {
                        // unsigned int -> unsigned int
                        var source = mesh.IndexBuffer.Bytes.Reinterpret <uint>(1);
                        jobHandle = new CopyIndicesJobs.UInt2UInt(
                            (uint)vertexOffset,
                            source,
                            new NativeSlice <uint>(indices, indexOffset, mesh.IndexBuffer.Count))
                                    .Schedule(mesh.IndexBuffer.Count, 1, jobHandle);
                        break;
                    }

                    default:
                        throw new ArgumentException($"unknown index buffer type: {mesh.IndexBuffer.ComponentType}");
                    }

                    vertexOffset += mesh.VertexBuffer.Count;
                    indexOffset  += mesh.IndexBuffer.Count;
                }

                jobHandle.Complete();

                resultMesh.SetIndexBufferParams(indexCount, IndexFormat.UInt32);
                resultMesh.SetIndexBufferData(indices, 0, 0, indexCount);
            }

            foreach (var disposable in disposables)
            {
                disposable.Dispose();
            }

            Profiler.EndSample();
        }
Exemplo n.º 2
0
        /// <summary>
        /// インデックスバッファを更新する
        /// MEMO: 出力に対するushortを考慮することをやめればかなりシンプルに書ける
        /// </summary>
        private static void UpdateIndices(MeshGroup meshGroup, int vertexCount, int indexCount, Mesh resultMesh)
        {
            Profiler.BeginSample("MeshImporterDivided.UpdateIndices");

            JobHandle jobHandle = default;

            var disposables = new List <IDisposable>();

            // 出力をushortにするべきかどうかを判別
            if (vertexCount < ushort.MaxValue)
            {
                var indices = new NativeArray <ushort>(indexCount, Allocator.TempJob);
                disposables.Add(indices);
                var indexOffset  = 0;
                var vertexOffset = 0;
                foreach (var mesh in meshGroup.Meshes)
                {
                    switch (mesh.IndexBuffer.ComponentType)
                    {
                    case AccessorValueType.SHORT:
                    {
                        // unsigned short -> unsigned short
                        var source = mesh.IndexBuffer.AsNativeArray <ushort>(Allocator.TempJob);
                        disposables.Add(source);
                        jobHandle = new CopyIndicesJobs.Ushort2Ushort(
                            (ushort)vertexOffset,
                            new NativeSlice <ushort>(source),
                            new NativeSlice <ushort>(indices, indexOffset, mesh.IndexBuffer.Count))
                                    .Schedule(mesh.IndexBuffer.Count, 1, jobHandle);
                        break;
                    }

                    case AccessorValueType.UNSIGNED_INT:
                    {
                        // unsigned int -> unsigned short
                        var source = mesh.IndexBuffer.AsNativeArray <uint>(Allocator.TempJob);
                        disposables.Add(source);
                        jobHandle = new CopyIndicesJobs.Uint2Ushort(
                            (ushort)vertexOffset,
                            source,
                            new NativeSlice <ushort>(indices, indexOffset, mesh.IndexBuffer.Count))
                                    .Schedule(mesh.IndexBuffer.Count, 1, jobHandle);
                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    vertexOffset += mesh.VertexBuffer.Count;
                    indexOffset  += mesh.IndexBuffer.Count;
                }

                jobHandle.Complete();

                resultMesh.SetIndexBufferParams(indexCount, IndexFormat.UInt16);
                resultMesh.SetIndexBufferData(indices, 0, 0, indexCount);
            }
            else
            {
                var indices = new NativeArray <uint>(indexCount, Allocator.TempJob);
                disposables.Add(indices);
                var indexOffset  = 0;
                var vertexOffset = 0;
                foreach (var mesh in meshGroup.Meshes)
                {
                    switch (mesh.IndexBuffer.ComponentType)
                    {
                    case AccessorValueType.SHORT:
                    {
                        // unsigned short -> unsigned int
                        var source = mesh.IndexBuffer.AsNativeArray <ushort>(Allocator.TempJob);
                        disposables.Add(source);
                        jobHandle = new CopyIndicesJobs.Ushort2Uint(
                            (uint)vertexOffset,
                            source,
                            new NativeSlice <uint>(indices, indexOffset, mesh.IndexBuffer.Count))
                                    .Schedule(mesh.IndexBuffer.Count, 1, jobHandle);
                        break;
                    }

                    case AccessorValueType.UNSIGNED_INT:
                    {
                        // unsigned int -> unsigned int
                        var source = mesh.IndexBuffer.AsNativeArray <uint>(Allocator.TempJob);
                        disposables.Add(source);
                        jobHandle = new CopyIndicesJobs.UInt2UInt(
                            (uint)vertexOffset,
                            source,
                            new NativeSlice <uint>(indices, indexOffset, mesh.IndexBuffer.Count))
                                    .Schedule(mesh.IndexBuffer.Count, 1, jobHandle);
                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    vertexOffset += mesh.VertexBuffer.Count;
                    indexOffset  += mesh.IndexBuffer.Count;
                }

                jobHandle.Complete();

                resultMesh.SetIndexBufferParams(indexCount, IndexFormat.UInt32);
                resultMesh.SetIndexBufferData(indices, 0, 0, indexCount);
            }

            foreach (var disposable in disposables)
            {
                disposable.Dispose();
            }

            Profiler.EndSample();
        }