コード例 #1
0
        public override unsafe bool ScheduleVertexColorJob(IGltfBuffers buffers, int colorAccessorIndex, NativeSlice <JobHandle> handles)
        {
            Profiler.BeginSample("ScheduleVertexColorJob");
            Profiler.BeginSample("AllocateNativeArray");
            buffers.GetAccessor(colorAccessorIndex, out var colorAcc, out var data, out var byteStride);
            if (colorAcc.isSparse)
            {
                logger.Error(LogCode.SparseAccessor, "color");
            }
            vData = new NativeArray <float4>(colorAcc.count, VertexBufferConfigBase.defaultAllocator);
            var vDataPtr = (byte *)NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(vData);

            Profiler.EndSample();

            var h = GetColors32Job(
                data,
                colorAcc.componentType,
                colorAcc.typeEnum,
                byteStride,
                vData
                );

            if (h.HasValue)
            {
                handles[0] = h.Value;
            }
            else
            {
                Profiler.EndSample();
                return(false);
            }
            Profiler.EndSample();
            return(true);
        }
コード例 #2
0
        public bool AddMorphTarget(
            IGltfBuffers buffers,
            int positionAccessorIndex,
            int normalAccessorIndex,
            int tangentAccessorIndex,
            ICodeLogger logger
            )
        {
            var newMorphTarget = new MorphTargetContext();
            var jobHandle      = newMorphTarget.ScheduleMorphTargetJobs(
                buffers,
                positionAccessorIndex,
                normalAccessorIndex,
                tangentAccessorIndex,
                logger
                );

            if (jobHandle.HasValue)
            {
                handles[currentIndex]  = jobHandle.Value;
                contexts[currentIndex] = newMorphTarget;
                currentIndex++;
            }
            else
            {
                return(false);
            }
            return(true);
        }
コード例 #3
0
 public abstract JobHandle?ScheduleVertexJobs(
     IGltfBuffers buffers,
     int positionAccessorIndex,
     int normalAccessorIndex,
     int tangentAccessorIndex,
     int[] uvAccessorIndices,
     int colorAccessorIndex,
     int weightsAccessorIndex,
     int jointsAccessorIndex
     );
コード例 #4
0
        public override unsafe bool ScheduleVertexUVJobs(IGltfBuffers buffers, int[] uvAccessorIndices, int vertexCount, NativeSlice <JobHandle> handles)
        {
            Profiler.BeginSample("ScheduleVertexUVJobs");
            Profiler.BeginSample("AllocateNativeArray");
            vData = new NativeArray <T>(vertexCount, VertexBufferConfigBase.defaultAllocator);
            var vDataPtr = (byte *)NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(vData);

            Profiler.EndSample();
            uvSetCount = uvAccessorIndices.Length;
            int outputByteStride = uvAccessorIndices.Length * 8;

            for (int i = 0; i < uvAccessorIndices.Length; i++)
            {
                var accIndex = uvAccessorIndices[i];
                buffers.GetAccessor(accIndex, out var uvAcc, out var data, out var byteStride);
                if (uvAcc.isSparse)
                {
                    logger.Error(LogCode.SparseAccessor, "UVs");
                }
                var h = GetUvsJob(
                    data,
                    uvAcc.count,
                    uvAcc.componentType,
                    byteStride,
                    (float2 *)(vDataPtr + (i * 8)),
                    outputByteStride,
                    uvAcc.normalized
                    );
                if (h.HasValue)
                {
                    handles[i] = h.Value;
                }
                else
                {
                    Profiler.EndSample();
                    return(false);
                }
            }
            Profiler.EndSample();
            return(true);
        }
コード例 #5
0
 public abstract bool ScheduleVertexUVJobs(IGltfBuffers buffers, int[] uvAccessorIndices, int vertexCount, NativeSlice <JobHandle> handles);
コード例 #6
0
        public unsafe JobHandle?ScheduleMorphTargetJobs(
            IGltfBuffers buffers,
            int positionAccessorIndex,
            int normalAccessorIndex,
            int tangentAccessorIndex,
            ICodeLogger logger
            )
        {
            Profiler.BeginSample("ScheduleMorphTargetJobs");

            buffers.GetAccessor(positionAccessorIndex, out var posAcc, out var posData, out var posByteStride);

            positions       = new Vector3[posAcc.count];
            positionsHandle = GCHandle.Alloc(positions, GCHandleType.Pinned);

            var jobCount = 1;

            if (posAcc.isSparse && posAcc.bufferView >= 0)
            {
                jobCount++;
            }

            Accessor nrmAcc             = null;
            void *   nrmInput           = null;
            int      nrmInputByteStride = 0;

            if (normalAccessorIndex >= 0)
            {
                normals       = new Vector3[posAcc.count];
                normalsHandle = GCHandle.Alloc(normals, GCHandleType.Pinned);
                buffers.GetAccessor(normalAccessorIndex, out nrmAcc, out nrmInput, out nrmInputByteStride);
                if (nrmAcc.isSparse && nrmAcc.bufferView >= 0)
                {
                    jobCount += 2;
                }
                else
                {
                    jobCount++;
                }
            }

            Accessor tanAcc             = null;
            void *   tanInput           = null;
            int      tanInputByteStride = 0;

            if (tangentAccessorIndex >= 0)
            {
                tangents       = new Vector3[posAcc.count];
                tangentsHandle = GCHandle.Alloc(tangents, GCHandleType.Pinned);
                buffers.GetAccessor(normalAccessorIndex, out tanAcc, out tanInput, out tanInputByteStride);
                if (tanAcc.isSparse && tanAcc.bufferView >= 0)
                {
                    jobCount += 2;
                }
                else
                {
                    jobCount++;
                }
            }

            NativeArray <JobHandle> handles = new NativeArray <JobHandle>(jobCount, VertexBufferConfigBase.defaultAllocator);
            var handleIndex = 0;

            fixed(void *dest = &(positions[0]))
            {
                JobHandle?h = null;

                if (posData != null)
                {
#if DEBUG
                    if (posAcc.normalized)
                    {
                        Debug.LogError("Normalized Positions will likely produce incorrect results. Please report this error at https://github.com/atteneder/glTFast/issues/new?assignees=&labels=bug&template=bug_report.md&title=Normalized%20Positions");
                    }
#endif
                    h = VertexBufferConfigBase.GetVector3sJob(
                        posData,
                        posAcc.count,
                        posAcc.componentType,
                        posByteStride,
                        (float3 *)dest,
                        12,
                        posAcc.normalized,
                        false // positional data never needs to be normalized
                        );
                    if (h.HasValue)
                    {
                        handles[handleIndex] = h.Value;
                        handleIndex++;
                    }
                    else
                    {
                        Profiler.EndSample();
                        return(null);
                    }
                }
                if (posAcc.isSparse)
                {
                    buffers.GetAccessorSparseIndices(posAcc.sparse.indices, out var posIndexData);
                    buffers.GetAccessorSparseValues(posAcc.sparse.values, out var posValueData);
                    var sparseJobHandle = VertexBufferConfigBase.GetVector3sSparseJob(
                        posIndexData,
                        posValueData,
                        posAcc.sparse.count,
                        posAcc.sparse.indices.componentType,
                        posAcc.componentType,
                        (float3 *)dest,
                        12,
                        dependsOn: ref h,
                        posAcc.normalized
                        );
                    if (sparseJobHandle.HasValue)
                    {
                        handles[handleIndex] = sparseJobHandle.Value;
                        handleIndex++;
                    }
                    else
                    {
                        Profiler.EndSample();
                        return(null);
                    }
                }
            }

            if (nrmAcc != null)
            {
                fixed(void *dest = &(normals[0]))
                {
                    JobHandle?h = null;

                    if (nrmAcc.bufferView >= 0)
                    {
                        h = VertexBufferConfigBase.GetVector3sJob(
                            nrmInput,
                            nrmAcc.count,
                            nrmAcc.componentType,
                            nrmInputByteStride,
                            (float3 *)dest,
                            12,
                            nrmAcc.normalized,
                            false // morph target normals are deltas -> don't normalize
                            );
                        if (h.HasValue)
                        {
                            handles[handleIndex] = h.Value;
                            handleIndex++;
                        }
                        else
                        {
                            Profiler.EndSample();
                            return(null);
                        }
                    }
                    if (nrmAcc.isSparse)
                    {
                        buffers.GetAccessorSparseIndices(nrmAcc.sparse.indices, out var indexData);
                        buffers.GetAccessorSparseValues(nrmAcc.sparse.values, out var valueData);
                        var sparseJobHandle = VertexBufferConfigBase.GetVector3sSparseJob(
                            indexData,
                            valueData,
                            nrmAcc.sparse.count,
                            nrmAcc.sparse.indices.componentType,
                            nrmAcc.componentType,
                            (float3 *)dest,
                            12,
                            dependsOn: ref h,
                            nrmAcc.normalized
                            );
                        if (sparseJobHandle.HasValue)
                        {
                            handles[handleIndex] = sparseJobHandle.Value;
                            handleIndex++;
                        }
                        else
                        {
                            Profiler.EndSample();
                            return(null);
                        }
                    }
                }
            }

            if (tanAcc != null)
            {
                fixed(void *dest = &(tangents[0]))
                {
                    JobHandle?h = null;

                    if (tanAcc.bufferView >= 0)
                    {
                        h = VertexBufferConfigBase.GetVector3sJob(
                            tanInput,
                            tanAcc.count,
                            tanAcc.componentType,
                            tanInputByteStride,
                            (float3 *)dest,
                            12,
                            tanAcc.normalized,
                            false // morph target tangents are deltas -> don't normalize
                            );
                        if (h.HasValue)
                        {
                            handles[handleIndex] = h.Value;
                            handleIndex++;
                        }
                        else
                        {
                            Profiler.EndSample();
                            return(null);
                        }
                    }
                    if (tanAcc.isSparse)
                    {
                        buffers.GetAccessorSparseIndices(tanAcc.sparse.indices, out var indexData);
                        buffers.GetAccessorSparseValues(tanAcc.sparse.values, out var valueData);
                        var sparseJobHandle = VertexBufferConfigBase.GetVector3sSparseJob(
                            indexData,
                            valueData,
                            tanAcc.sparse.count,
                            tanAcc.sparse.indices.componentType,
                            tanAcc.componentType,
                            (float3 *)dest,
                            12,
                            dependsOn: ref h,
                            tanAcc.normalized
                            );
                        if (sparseJobHandle.HasValue)
                        {
                            handles[handleIndex] = sparseJobHandle.Value;
                            handleIndex++;
                        }
                        else
                        {
                            Profiler.EndSample();
                            return(null);
                        }
                    }
                }
            }

            var handle = (jobCount > 1) ? JobHandle.CombineDependencies(handles) : handles[0];
            handles.Dispose();
            Profiler.EndSample();
            return(handle);
        }
コード例 #7
0
        public override unsafe JobHandle?ScheduleVertexBonesJob(
            IGltfBuffers buffers,
            int weightsAccessorIndex,
            int jointsAccessorIndex
            )
        {
            Profiler.BeginSample("ScheduleVertexBonesJob");
            Profiler.BeginSample("AllocateNativeArray");

            buffers.GetAccessor(weightsAccessorIndex, out var weightsAcc, out var weightsData, out var weightsByteStride);
            if (weightsAcc.isSparse)
            {
                logger.Error(LogCode.SparseAccessor, "bone weights");
            }
            vData = new NativeArray <VBones>(weightsAcc.count, VertexBufferConfigBase.defaultAllocator);
            var vDataPtr = (byte *)NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(vData);

            Profiler.EndSample();

            JobHandle weightsHandle;
            JobHandle jointsHandle;

            {
                var h = GetWeightsJob(
                    weightsData,
                    weightsAcc.count,
                    weightsAcc.componentType,
                    weightsByteStride,
                    (float4 *)vDataPtr,
                    32,
                    weightsAcc.normalized
                    );
                if (h.HasValue)
                {
                    weightsHandle = h.Value;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            {
                buffers.GetAccessor(jointsAccessorIndex, out var jointsAcc, out var jointsData, out var jointsByteStride);
                if (jointsAcc.isSparse)
                {
                    logger.Error(LogCode.SparseAccessor, "bone joints");
                }
                var h = GetJointsJob(
                    jointsData,
                    jointsAcc.count,
                    jointsAcc.componentType,
                    jointsByteStride,
                    (uint4 *)(vDataPtr + 16),
                    32,
                    logger
                    );
                if (h.HasValue)
                {
                    jointsHandle = h.Value;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            var jobHandle = JobHandle.CombineDependencies(weightsHandle, jointsHandle);

            var skinWeights = (int)QualitySettings.skinWeights;

            if (skinWeights < 4)
            {
                var job = new SortJointsByWeightsJob {
                    bones       = vData,
                    skinWeights = math.max(1, skinWeights)
                };
                jobHandle = job.Schedule(vData.Length, GltfImport.DefaultBatchCount, jobHandle);
            }

            Profiler.EndSample();
            return(jobHandle);
        }
コード例 #8
0
 public abstract JobHandle?ScheduleVertexBonesJob(
     IGltfBuffers buffers,
     int weightsAccessorIndex,
     int jointsAccessorIndex
     );
コード例 #9
0
 public abstract bool ScheduleVertexColorJob(IGltfBuffers buffers, int colorAccessorIndex, NativeSlice <JobHandle> handles);
コード例 #10
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);
        }
コード例 #11
0
        public override unsafe JobHandle?ScheduleVertexBonesJob(
            IGltfBuffers buffers,
            int weightsAccessorIndex,
            int jointsAccessorIndex
            )
        {
            Profiler.BeginSample("ScheduleVertexBonesJob");
            Profiler.BeginSample("AllocateNativeArray");

            buffers.GetAccessor(weightsAccessorIndex, out var weightsAcc, out var weightsData, out var weightsByteStride);
            if (weightsAcc.isSparse)
            {
                logger.Error(LogCode.SparseAccessor, "bone weights");
            }
            vData = new NativeArray <VBones>(weightsAcc.count, VertexBufferConfigBase.defaultAllocator);
            var vDataPtr = (byte *)NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(vData);

            Profiler.EndSample();

            JobHandle weightsHandle;
            JobHandle jointsHandle;

            {
                var h = GetWeightsJob(
                    weightsData,
                    weightsAcc.count,
                    weightsAcc.componentType,
                    weightsByteStride,
                    (float4 *)vDataPtr,
                    32,
                    weightsAcc.normalized
                    );
                if (h.HasValue)
                {
                    weightsHandle = h.Value;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            {
                buffers.GetAccessor(jointsAccessorIndex, out var jointsAcc, out var jointsData, out var jointsByteStride);
                if (jointsAcc.isSparse)
                {
                    logger.Error(LogCode.SparseAccessor, "bone joints");
                }
                var h = GetJointsJob(
                    jointsData,
                    jointsAcc.count,
                    jointsAcc.componentType,
                    jointsByteStride,
                    (uint4 *)(vDataPtr + 16),
                    32,
                    logger
                    );
                if (h.HasValue)
                {
                    jointsHandle = h.Value;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            var jobHandle = JobHandle.CombineDependencies(weightsHandle, jointsHandle);

            var skinWeights = (int)QualitySettings.skinWeights;

#if UNITY_EDITOR
            // If this is design-time import, fix and import all weights.
            if (!UnityEditor.EditorApplication.isPlaying || skinWeights < 4)
            {
                if (!UnityEditor.EditorApplication.isPlaying)
                {
                    skinWeights = 4;
                }
#else
            if (skinWeights < 4)
            {
#endif
                var job = new SortAndRenormalizeBoneWeightsJob {
                    bones       = vData,
                    skinWeights = math.max(1, skinWeights)
                };
                jobHandle = job.Schedule(vData.Length, GltfImport.DefaultBatchCount, jobHandle);
            }
#if GLTFAST_SAFE
            else
            {
                // Re-normalizing alone is sufficient
                var job = new RenormalizeBoneWeightsJob {
                    bones = vData,
                };
                jobHandle = job.Schedule(vData.Length, GltfImport.DefaultBatchCount, jobHandle);
            }
#endif

            Profiler.EndSample();
            return(jobHandle);
        }