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); }
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); }