Exemplo n.º 1
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);
        }