Example #1
0
        public override unsafe JobHandle?ScheduleVertexJobs(
            VertexInputData posInput,
            VertexInputData?nrmInput     = null,
            VertexInputData?tanInput     = null,
            VertexInputData[] uvInputs   = null,
            VertexInputData?colorInput   = null,
            VertexInputData?weightsInput = null,
            VertexInputData?jointsInput  = null
            )
        {
            Profiler.BeginSample("ScheduleVertexJobs");
            Profiler.BeginSample("AllocateNativeArray");
            vData = new NativeArray <VType>(posInput.count, defaultAllocator);
            var vDataPtr = (byte *)NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(vData);

            Profiler.EndSample();

            int jobCount         = 1;
            int outputByteStride = 12; // sizeof Vector3

            hasNormals = nrmInput.HasValue || calculateNormals;
            if (hasNormals)
            {
                if (nrmInput.HasValue)
                {
                    jobCount++;
                }
                outputByteStride += 12;
            }

            hasTangents = tanInput.HasValue || calculateTangents;
            if (hasTangents)
            {
                if (tanInput.HasValue)
                {
                    jobCount++;
                }
                outputByteStride += 16;
            }

            if (uvInputs != null && uvInputs.Length > 0)
            {
                jobCount += uvInputs.Length;
                switch (uvInputs.Length)
                {
                case 1:
                    texCoords = new VertexBufferTexCoords <VTexCoord1>();
                    break;

                default:
                    texCoords = new VertexBufferTexCoords <VTexCoord2>();
                    break;
                }
            }

            hasColors = colorInput.HasValue;
            if (hasColors)
            {
                jobCount++;
                colors = new VertexBufferColors();
            }

            hasBones = weightsInput.HasValue && jointsInput.HasValue;
            if (hasBones)
            {
                jobCount += 2;
                bones     = new VertexBufferBones();
            }

            NativeArray <JobHandle> handles = new NativeArray <JobHandle>(jobCount, Allocator.Temp);
            int handleIndex = 0;

            fixed(void *input = &(posInput.buffer[posInput.startOffset]))
            {
                var h = GetVector3sJob(
                    input,
                    posInput.count,
                    posInput.type,
                    posInput.byteStride,
                    (Vector3 *)vDataPtr,
                    outputByteStride,
                    posInput.normalize
                    );

                if (h.HasValue)
                {
                    handles[handleIndex] = h.Value;
                    handleIndex++;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            if (nrmInput.HasValue)
            {
                fixed(void *input = &(nrmInput.Value.buffer[nrmInput.Value.startOffset]))
                {
                    var h = GetVector3sJob(
                        input,
                        nrmInput.Value.count,
                        nrmInput.Value.type,
                        nrmInput.Value.byteStride,
                        (Vector3 *)(vDataPtr + 12),
                        outputByteStride,
                        nrmInput.Value.normalize
                        );

                    if (h.HasValue)
                    {
                        handles[handleIndex] = h.Value;
                        handleIndex++;
                    }
                    else
                    {
                        Profiler.EndSample();
                        return(null);
                    }
                }
            }

            if (tanInput.HasValue)
            {
                fixed(void *input = &(tanInput.Value.buffer[tanInput.Value.startOffset]))
                {
                    var h = GetTangentsJob(
                        input,
                        tanInput.Value.count,
                        tanInput.Value.type,
                        tanInput.Value.byteStride,
                        (Vector4 *)(vDataPtr + 24),
                        outputByteStride,
                        tanInput.Value.normalize
                        );

                    if (h.HasValue)
                    {
                        handles[handleIndex] = h.Value;
                        handleIndex++;
                    }
                    else
                    {
                        Profiler.EndSample();
                        return(null);
                    }
                }
            }

            if (texCoords != null)
            {
                texCoords.ScheduleVertexUVJobs(uvInputs, new NativeSlice <JobHandle>(handles, handleIndex, uvInputs.Length));
                handleIndex++;
            }

            if (hasColors)
            {
                colors.ScheduleVertexColorJob(colorInput.Value, new NativeSlice <JobHandle>(handles, handleIndex, 1));
                handleIndex++;
            }

            if (hasBones)
            {
                bones.ScheduleVertexBonesJob(weightsInput.Value, jointsInput.Value, new NativeSlice <JobHandle>(handles, handleIndex, 2));
                handleIndex += 2;
            }

            var handle = (jobCount > 1) ? JobHandle.CombineDependencies(handles) : handles[0];

            handles.Dispose();
            Profiler.EndSample();
            return(handle);
        }
Example #2
0
        public override unsafe JobHandle?ScheduleVertexJobs(
            IGltfBuffers buffers,
            int positionAccessorIndex,
            int normalAccessorIndex,
            int tangentAccessorIndex,
            int[] uvAccessorIndices,
            int colorAccessorIndex,
            int weightsAccessorIndex,
            int jointsAccessorIndex
            )
        {
            buffers.GetAccessor(positionAccessorIndex, out var posAcc, out var posData, out var posByteStride);

            Profiler.BeginSample("ScheduleVertexJobs");
            Profiler.BeginSample("AllocateNativeArray");
            vData = new NativeArray <VType>(posAcc.count, defaultAllocator);
            var vDataPtr = (byte *)vData.GetUnsafeReadOnlyPtr();

            Profiler.EndSample();

            bounds = posAcc.TryGetBounds();

            int jobCount         = 1;
            int outputByteStride = 12; // sizeof Vector3

            if (posAcc.isSparse && posAcc.bufferView >= 0)
            {
                jobCount++;
            }
            if (normalAccessorIndex >= 0)
            {
                jobCount++;
                hasNormals = true;
            }
            hasNormals |= calculateNormals;
            if (hasNormals)
            {
                outputByteStride += 12;
            }

            if (tangentAccessorIndex >= 0)
            {
                jobCount++;
                hasTangents = true;
            }
            hasTangents |= calculateTangents;
            if (hasTangents)
            {
                outputByteStride += 16;
            }

            if (uvAccessorIndices != null && uvAccessorIndices.Length > 0)
            {
                // More than two UV sets are not supported yet
                Assert.IsTrue(uvAccessorIndices.Length < 3);

                jobCount += uvAccessorIndices.Length;
                switch (uvAccessorIndices.Length)
                {
                case 1:
                    texCoords = new VertexBufferTexCoords <VTexCoord1>(logger);
                    break;

                default:
                    texCoords = new VertexBufferTexCoords <VTexCoord2>(logger);
                    break;
                }
            }

            hasColors = colorAccessorIndex >= 0;
            if (hasColors)
            {
                jobCount++;
                colors = new VertexBufferColors();
            }

            hasBones = weightsAccessorIndex >= 0 && jointsAccessorIndex >= 0;
            if (hasBones)
            {
                jobCount++;
                bones = new VertexBufferBones(logger);
            }

            NativeArray <JobHandle> handles = new NativeArray <JobHandle>(jobCount, defaultAllocator);
            int handleIndex = 0;

            {
                JobHandle?h = null;
                if (posAcc.bufferView >= 0)
                {
                    h = GetVector3sJob(
                        posData,
                        posAcc.count,
                        posAcc.componentType,
                        posByteStride,
                        (float3 *)vDataPtr,
                        outputByteStride,
                        posAcc.normalized,
                        false // positional data never needs to be normalized
                        );
                }
                if (posAcc.isSparse)
                {
                    buffers.GetAccessorSparseIndices(posAcc.sparse.indices, out var posIndexData);
                    buffers.GetAccessorSparseValues(posAcc.sparse.values, out var posValueData);
                    var sparseJobHandle = GetVector3sSparseJob(
                        posIndexData,
                        posValueData,
                        posAcc.sparse.count,
                        posAcc.sparse.indices.componentType,
                        posAcc.componentType,
                        (float3 *)vDataPtr,
                        outputByteStride,
                        dependsOn: ref h,
                        posAcc.normalized
                        );
                    if (sparseJobHandle.HasValue)
                    {
                        handles[handleIndex] = sparseJobHandle.Value;
                        handleIndex++;
                    }
                    else
                    {
                        Profiler.EndSample();
                        return(null);
                    }
                }
                if (h.HasValue)
                {
                    handles[handleIndex] = h.Value;
                    handleIndex++;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            if (normalAccessorIndex >= 0)
            {
                buffers.GetAccessor(normalAccessorIndex, out var nrmAcc, out var input, out var inputByteStride);
                if (nrmAcc.isSparse)
                {
                    logger.Error(LogCode.SparseAccessor, "normals");
                }
                var h = GetVector3sJob(
                    input,
                    nrmAcc.count,
                    nrmAcc.componentType,
                    inputByteStride,
                    (float3 *)(vDataPtr + 12),
                    outputByteStride,
                    nrmAcc.normalized,
                    true // normals need to be unit length
                    );
                if (h.HasValue)
                {
                    handles[handleIndex] = h.Value;
                    handleIndex++;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            if (tangentAccessorIndex >= 0)
            {
                buffers.GetAccessor(tangentAccessorIndex, out var tanAcc, out var input, out var inputByteStride);
                if (tanAcc.isSparse)
                {
                    logger.Error(LogCode.SparseAccessor, "tangents");
                }
                var h = GetTangentsJob(
                    input,
                    tanAcc.count,
                    tanAcc.componentType,
                    inputByteStride,
                    (float4 *)(vDataPtr + 24),
                    outputByteStride,
                    tanAcc.normalized
                    );
                if (h.HasValue)
                {
                    handles[handleIndex] = h.Value;
                    handleIndex++;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            if (texCoords != null)
            {
                texCoords.ScheduleVertexUVJobs(
                    buffers,
                    uvAccessorIndices,
                    posAcc.count,
                    new NativeSlice <JobHandle>(
                        handles,
                        handleIndex,
                        uvAccessorIndices.Length
                        )
                    );
                handleIndex += uvAccessorIndices.Length;
            }

            if (hasColors)
            {
                colors.ScheduleVertexColorJob(
                    buffers,
                    colorAccessorIndex,
                    new NativeSlice <JobHandle>(
                        handles,
                        handleIndex,
                        1
                        )
                    );
                handleIndex++;
            }

            if (hasBones)
            {
                var h = bones.ScheduleVertexBonesJob(
                    buffers,
                    weightsAccessorIndex,
                    jointsAccessorIndex
                    );
                if (h.HasValue)
                {
                    handles[handleIndex] = h.Value;
                    handleIndex++;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            var handle = (jobCount > 1) ? JobHandle.CombineDependencies(handles) : handles[0];

            handles.Dispose();
            Profiler.EndSample();
            return(handle);
        }