internal unsafe static void CalculateBounds(this SpriteSkin spriteSkin)
        {
            Debug.Assert(spriteSkin.isValid);
            var sprite = spriteSkin.sprite;


            var   deformVertexData = new NativeArray <byte>(sprite.GetVertexStreamSize() * sprite.GetVertexCount(), Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            void *dataPtr          = NativeArrayUnsafeUtility.GetUnsafePtr(deformVertexData);
            var   deformedPosSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <Vector3>(dataPtr, sprite.GetVertexStreamSize(), sprite.GetVertexCount());

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref deformedPosSlice, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(deformVertexData));
#endif

            var rootBone = spriteSkin.rootBone;
            spriteSkin.Bake(ref deformVertexData);
            var bounds = new Bounds();

            if (deformVertexData.Length > 0)
            {
                bounds.min = rootBone.InverseTransformPoint(deformedPosSlice[0]);
                bounds.max = bounds.min;
            }

            foreach (var v in deformedPosSlice)
            {
                bounds.Encapsulate(rootBone.InverseTransformPoint(v));
            }

            bounds.extents    = Vector3.Scale(bounds.extents, new Vector3(1.25f, 1.25f, 1f));
            spriteSkin.bounds = bounds;
        }
示例#2
0
    GetReadOnlySpan <T>(this NativeSlice <T> slice)
        where T : unmanaged
    {
        var ptr = NativeSliceUnsafeUtility.GetUnsafeReadOnlyPtr(slice);

        return(new Span <T>(ptr, slice.Length));
    }
示例#3
0
            public NetworkEvent.Type PopEvent(out DataStreamReader bs)
            {
                bs = default;
                if (m_IncomingEvents->Length == 0)
                {
                    return(NetworkEvent.Type.Empty);
                }

                var ev = UnsafeUtility.ReadArrayElement <DriverEvent>(m_IncomingEvents->Ptr, 0);

                if (m_IncomingEvents->Length > 0)
                {
                    //m_IncomingEvents->RemoveAtSwapBack<DriverEvent>(0);
                    m_IncomingEvents->Length--;
                    UnsafeUtility.MemMove(m_IncomingEvents->Ptr, (byte *)m_IncomingEvents->Ptr + sizeof(DriverEvent), sizeof(DriverEvent) * m_IncomingEvents->Length);
                }

                if (ev.Type == NetworkEvent.Type.Data)
                {
                    var slice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <byte>((byte *)m_DataStream->Ptr + ev.StreamOffset, sizeof(byte), ev.Length);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref slice, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle());
#endif

                    bs = new DataStreamReader(slice);
                }

                return(ev.Type);
            }
示例#4
0
        public static NativeSlice <T> GetVertexAttribute <T>(this Sprite sprite, VertexAttribute channel) where T : struct
        {
            SpriteDataAccessExtensions.CheckAttributeTypeMatchesAndThrow <T>(channel);
            SpriteChannelInfo channelInfo = SpriteDataAccessExtensions.GetChannelInfo(sprite, channel);
            NativeSlice <T>   result      = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <T>(channelInfo.buffer, channelInfo.offset, channelInfo.count, channelInfo.stride);

            NativeSliceUnsafeUtility.SetAtomicSafetyHandle <T>(ref result, sprite.GetSafetyHandle());
            return(result);
        }
        public unsafe static NativeSlice <T> GetVertexAttribute <T>(this Sprite sprite, VertexAttribute channel) where T : struct
        {
            CheckAttributeTypeMatchesAndThrow <T>(channel);
            var info   = GetChannelInfo(sprite, channel);
            var buffer = (byte *)(info.buffer) + info.offset;
            var slice  = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <T>(buffer, info.stride, info.count);

            return(slice);
        }
示例#6
0
        private static AtomicSafetyHandle CreateSafetyChecks <T>(ref NativeSlice <T> array) where T : struct
        {
            var handle = AtomicSafetyHandle.Create();

            AtomicSafetyHandle.SetAllowSecondaryVersionWriting(handle, true);
            AtomicSafetyHandle.UseSecondaryVersion(ref handle);
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle <T>(ref array, handle);
            return(handle);
        }
        public unsafe NativeSlice <T> ToNativeSlice()
        {
            var p = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <T>(data.ToPointer(), stride, length);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref p, safetyHandle);
#endif
            return(p);
        }
        public unsafe NatliveSliceIntPtr(NativeSlice <T> nativeSlice)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            safetyHandle = NativeSliceUnsafeUtility.GetAtomicSafetyHandle(nativeSlice);
#endif
            data   = new IntPtr(nativeSlice.GetUnsafeReadOnlyPtr());
            length = nativeSlice.Length;
            stride = nativeSlice.Stride;
        }
示例#9
0
        /// <summary>
        /// Writes a frame of input to the file.
        /// </summary>
        /// <param name="inputs">a frame of input to write.</param>
        public unsafe void WriteInputs(NativeSlice <PlayerInput> inputs)
        {
            Assert.IsTrue(inputs.Length == _config.PlayerCount);
            var ptr  = (byte *)NativeSliceUnsafeUtility.GetUnsafeReadOnlyPtr(inputs);
            int size = _config.PlayerCount * UnsafeUtility.SizeOf <PlayerInput>();

            _writer.Write(XXHash.Hash64(ptr, size));
            _writer.WriteBytes(ptr, size);
        }
示例#10
0
        private unsafe NativeSlice <T> GetChannelDataArray <T>(SpriteShapeDataType dataType, VertexAttribute channel) where T : struct
        {
            this.RefreshSafetyHandle(dataType);
            SpriteChannelInfo channelInfo = this.GetChannelInfo(channel);
            byte *            dataPointer = (byte *)channelInfo.buffer + channelInfo.offset;
            NativeSlice <T>   result      = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <T>((void *)dataPointer, channelInfo.stride, channelInfo.count);

            NativeSliceUnsafeUtility.SetAtomicSafetyHandle <T>(ref result, this.GetSafetyHandle(dataType));
            return(result);
        }
        /// <summary>
        /// 切り取ったバイト配列を新規で確保したメモリにコピーし、それを文字列用のポインタとして返す
        /// </summary>
        /// <param name="source">ソース</param>
        /// <param name="start">切り取り開始位置</param>
        /// <param name="length">データの長さ</param>
        /// <param name="allocator">Allocator</param>
        /// <returns>文字列のポインタ</returns>
        StringPtr SliceToStringPtr(NativeArray <byte> source, int start, int length, Allocator allocator)
        {
            var   slice  = new NativeSlice <byte>(source, start, length);
            byte *arrPtr = (byte *)UnsafeUtility.Malloc(length, UnsafeUtility.AlignOf <byte>(), allocator);

            UnsafeUtility.MemClear(arrPtr, length);
            UnsafeUtility.MemCpy(arrPtr, NativeSliceUnsafeUtility.GetUnsafePtr(slice), length);
            return(new StringPtr {
                Data = arrPtr, Length = length
            });
        }
        unsafe private NativeSlice <T> GetChannelDataArray <T>(SpriteShapeDataType dataType, VertexAttribute channel) where T : struct
        {
            RefreshSafetyHandle(dataType);

            var info   = GetChannelInfo(channel);
            var buffer = (byte *)(info.buffer) + info.offset;
            var slice  = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <T>(buffer, info.stride, info.count);

            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref slice, GetSafetyHandle(dataType));
            return(slice);
        }
示例#13
0
        /// <summary>
        /// Reads a frame of input to the file.
        /// </summary>
        /// <param name="inputs">a frame of input to read.</param>
        public unsafe void ReadInputs(NativeSlice <PlayerInput> inputs)
        {
            Assert.IsTrue(inputs.Length == _config.PlayerCount);
            var   ptr      = (byte *)NativeSliceUnsafeUtility.GetUnsafePtr(inputs);
            int   size     = _config.PlayerCount * UnsafeUtility.SizeOf <PlayerInput>();
            ulong checksum = _reader.ReadULong();

            _reader.ReadBytes(ptr, size);
            ulong hash = XXHash.Hash64(ptr, size);

            Assert.AreEqual(checksum, hash);
        }
示例#14
0
        public unsafe void Execute(int i)
        {
            var   spriteSkin        = spriteSkinData[i];
            byte *deformedPosOffset = (byte *)vertices.GetUnsafePtr();
            NativeSlice <float3> deformableVerticesFloat3 = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <float3>(deformedPosOffset + spriteSkin.deformVerticesStartPos, spriteSkin.spriteVertexStreamSize, spriteSkin.spriteVertexCount);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref deformableVerticesFloat3, NativeSliceUnsafeUtility.GetAtomicSafetyHandle(vertices));
#endif

            bounds[i] = SpriteSkinUtility.CalculateSpriteSkinBounds(deformableVerticesFloat3);
        }
示例#15
0
        /// <summary>
        /// Create a NativeSlice with access to the raw data in the writer, the data size
        /// (start to length) must not exceed the total size of the array or
        /// an exception will be thrown.
        /// </summary>
        /// <param name="start"></param>
        /// <param name="length"></param>
        public NativeSlice <byte> GetNativeSlice(int start, int length)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            ValidateSizeParameters(start, length, length);
#endif

            var slice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <byte>(m_Data->buffer + start, 1,
                                                                                         length);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref slice, m_Safety);
#endif
            return(slice);
        }
示例#16
0
    //-----------------------------------------------------------------------------
    public unsafe static void CopyMatrices(ComponentDataArray <TransformMatrix> transforms, int beginIndex, int length, Matrix4x4[] outMatrices)
    {
        fixed(Matrix4x4 *matricesPtr = outMatrices)
        {
            Assert.AreEqual(sizeof(Matrix4x4), sizeof(TransformMatrix));
            var matricesSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <TransformMatrix>(matricesPtr, sizeof(Matrix4x4), length);

                #if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref matricesSlice, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle());
                #endif
            transforms.CopyTo(matricesSlice, beginIndex);
        }
    }
示例#17
0
        // This is the ugly bit, necessary until Graphics.DrawMeshInstanced supports NativeArrays pulling the data in from a job.
        public unsafe static Vector4[] CopyToArray(this NativeSlice <Vector4> src, Vector4[] dst) // where T:struct
        {
            fixed(Vector4 *p = dst)
            {
                UnityEngine.Assertions.Assert.IsTrue(UnsafeUtility.IsBlittable <Vector4>());
                var s = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <Vector4>(p, UnsafeUtility.SizeOf <Vector4>(), src.Length);

                    #if ENABLE_UNITY_COLLECTIONS_CHECKS
                NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref s, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle());
                    #endif
                s.CopyFrom(src);
            }

            return(dst);
        }
示例#18
0
        public DataStreamReader(NativeSlice <byte> slice)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            m_Safety = NativeSliceUnsafeUtility.GetAtomicSafetyHandle(slice);
#endif
            m_bufferPtr = (byte *)slice.GetUnsafeReadOnlyPtr();
            m_Length    = slice.Length;

            uint test = 1;
            unsafe
            {
                byte *test_b = (byte *)&test;
                IsLittleEndian = test_b[0] == 1;
            }
        }
示例#19
0
    public unsafe static void CopyMatrices(NativeArray <LocalToWorld> transforms, int beginIndex, int length, Matrix4x4[] outMatrices)
    {
        fixed(Matrix4x4 *matricesPtr = outMatrices)
        {
            Assert.AreEqual(sizeof(Matrix4x4), sizeof(LocalToWorld));

            var matricesSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <LocalToWorld>(matricesPtr, sizeof(Matrix4x4), length);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref matricesSlice, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle());
#endif

            matricesSlice.CopyFrom(transforms.Slice(beginIndex, length));
        }
    }
        public unsafe static AsyncRequestNativeArrayData CreateAndCheckAccess <T>(NativeSlice <T> array) where T : struct
        {
            AsyncRequestNativeArrayData result = default(AsyncRequestNativeArrayData);

            result.nativeArrayBuffer = array.GetUnsafePtr <T>();
            result.lengthInBytes     = (long)array.Length * (long)UnsafeUtility.SizeOf <T>();
            AtomicSafetyHandle atomicSafetyHandle = NativeSliceUnsafeUtility.GetAtomicSafetyHandle <T>(array);
            int *ptr  = (int *)((void *)atomicSafetyHandle.versionNode);
            bool flag = atomicSafetyHandle.version != (*ptr & -6);

            if (flag)
            {
                AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut(atomicSafetyHandle);
            }
            result.safetyHandle = atomicSafetyHandle;
            return(result);
        }
示例#21
0
        // This is the ugly bit, necessary until Graphics.DrawMeshInstanced supports NativeArrays pulling the data in from a job.
        public unsafe static void CopyMatrices(ComponentDataArray <TransformMatrix> transforms, int beginIndex, int length, Matrix4x4[] outMatrices)
        {
            // @TODO: This is using unsafe code because the Unity DrawInstances API takes a Matrix4x4[] instead of NativeArray.
            // We want to use the ComponentDataArray.CopyTo method
            // because internally it uses memcpy to copy the data,
            // if the nativeslice layout matches the layout of the component data. It's very fast...
            fixed(Matrix4x4 *matricesPtr = outMatrices)
            {
                Assert.AreEqual(sizeof(Matrix4x4), sizeof(TransformMatrix));
                var matricesSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <TransformMatrix>(matricesPtr, sizeof(Matrix4x4), length);

                    #if ENABLE_UNITY_COLLECTIONS_CHECKS
                NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref matricesSlice, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle());
                    #endif
                transforms.CopyTo(matricesSlice, beginIndex);
            }
        }
示例#22
0
        internal static unsafe void UpdateBounds(this SpriteSkin spriteSkin, NativeArray <byte> deformedVertices)
        {
            byte *deformedPosOffset                = (byte *)NativeArrayUnsafeUtility.GetUnsafePtr(deformedVertices);
            var   spriteVertexCount                = spriteSkin.sprite.GetVertexCount();
            var   spriteVertexStreamSize           = spriteSkin.sprite.GetVertexStreamSize();
            NativeSlice <float3> deformedPositions = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <float3>(deformedPosOffset, spriteVertexStreamSize, spriteVertexCount);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            var handle = CreateSafetyChecks <float3>(ref deformedPositions);
#endif
            spriteSkin.bounds = CalculateSpriteSkinBounds(deformedPositions);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            DisposeSafetyChecks(handle);
#endif
            InternalEngineBridge.SetLocalAABB(spriteSkin.spriteRenderer, spriteSkin.bounds);
        }
示例#23
0
        public unsafe void Execute(int i)
        {
            int j = vertexLookupData[i].x;
            int k = vertexLookupData[i].y;

            PerSkinJobData perSkinData = perSkinJobData[j];
            var            spriteSkin  = spriteSkinData[j];
            float3         srcVertex   = spriteSkin.vertices[k];
            float4         tangents    = spriteSkin.tangents[k];
            var            influence   = spriteSkin.boneWeights[k];

            int bone0 = influence.boneIndex0 + perSkinData.bindPosesIndex.x;
            int bone1 = influence.boneIndex1 + perSkinData.bindPosesIndex.x;
            int bone2 = influence.boneIndex2 + perSkinData.bindPosesIndex.x;
            int bone3 = influence.boneIndex3 + perSkinData.bindPosesIndex.x;

            byte *deformedPosOffset = (byte *)vertices.GetUnsafePtr();
            byte *deformedPosStart  = deformedPosOffset + spriteSkin.deformVerticesStartPos;
            NativeSlice <float3> deformableVerticesFloat3 = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <float3>(deformedPosStart, spriteSkin.spriteVertexStreamSize, spriteSkin.spriteVertexCount);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref deformableVerticesFloat3, NativeSliceUnsafeUtility.GetAtomicSafetyHandle(vertices));
#endif
            if (spriteSkin.hasTangents)
            {
                byte *deformedTanOffset        = deformedPosStart + spriteSkin.tangentVertexOffset;
                var   deformableTangentsFloat4 = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <float4>(deformedTanOffset, spriteSkin.spriteVertexStreamSize, spriteSkin.spriteVertexCount);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref deformableTangentsFloat4, NativeSliceUnsafeUtility.GetAtomicSafetyHandle(vertices));
#endif
                var tangent = new float4(tangents.xyz, 0.0f);
                tangent =
                    math.mul(finalBoneTransforms[bone0], tangent) * influence.weight0 +
                    math.mul(finalBoneTransforms[bone1], tangent) * influence.weight1 +
                    math.mul(finalBoneTransforms[bone2], tangent) * influence.weight2 +
                    math.mul(finalBoneTransforms[bone3], tangent) * influence.weight3;
                deformableTangentsFloat4[k] = new float4(math.normalize(tangent.xyz), tangents.w);
            }

            deformableVerticesFloat3[k] =
                math.transform(finalBoneTransforms[bone0], srcVertex) * influence.weight0 +
                math.transform(finalBoneTransforms[bone1], srcVertex) * influence.weight1 +
                math.transform(finalBoneTransforms[bone2], srcVertex) * influence.weight2 +
                math.transform(finalBoneTransforms[bone3], srcVertex) * influence.weight3;
        }
示例#24
0
        internal unsafe static void CalculateBounds(this SpriteSkin spriteSkin)
        {
            Debug.Assert(spriteSkin.isValid);
            var sprite = spriteSkin.sprite;


            var   deformVertexData = new NativeArray <byte>(sprite.GetVertexStreamSize() * sprite.GetVertexCount(), Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            void *dataPtr          = NativeArrayUnsafeUtility.GetUnsafePtr(deformVertexData);
            var   deformedPosSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <Vector3>(dataPtr, sprite.GetVertexStreamSize(), sprite.GetVertexCount());

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref deformedPosSlice, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(deformVertexData));
#endif

            spriteSkin.Bake(ref deformVertexData);
            UpdateBounds(spriteSkin, deformVertexData);
            deformVertexData.Dispose();
        }
示例#25
0
    public static unsafe void CopyIntegers(NativeList <int> src, List <int> dst)
    {
        if (dst.Capacity < src.Length)
        {
            dst.Capacity = src.Length;
        }

        var array = NoAllocHelpers.ExtractArrayFromListT(dst);

        fixed(int *arrayPtr = array)
        {
            var dstSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <int>(arrayPtr, sizeof(int), src.Length);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref dstSlice, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle());
#endif
            dstSlice.CopyFrom((NativeArray <int>)src);
        }

        NoAllocHelpers.ResizeList(dst, src.Length);
    }
示例#26
0
    GetNativeSlice <T>(this ReadOnlySpan <T> span, int offset, int stride)
        where T : unmanaged
    {
        fixed(void *ptr = &span.GetPinnableReference())
        {
            var headPtr      = (T *)ptr + offset;
            var strideInByte = sizeof(T) * stride;
            var elementCount = span.Length / stride - offset / stride;

            var slice =
                NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <T>
                    (headPtr, strideInByte, elementCount);

          #if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeSliceUnsafeUtility.SetAtomicSafetyHandle
                (ref slice, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle());
          #endif

            return(slice);
        }
    }
        public static AsyncRequestNativeArrayData CreateAndCheckAccess <T>(NativeSlice <T> array) where T : struct
        {
            if (AtomicSafetyHandle.IsTempMemoryHandle(array.m_Safety))
            {
                throw new ArgumentException("AsyncGPUReadback cannot use Temp memory as input since the result may only become available at an unspecified point in the future.");
            }

            var nativeArrayData = new AsyncRequestNativeArrayData();

            nativeArrayData.nativeArrayBuffer = array.GetUnsafePtr();
            nativeArrayData.lengthInBytes     = (long)array.Length * UnsafeUtility.SizeOf <T>();
            var handle     = NativeSliceUnsafeUtility.GetAtomicSafetyHandle(array);
            var versionPtr = (int *)handle.versionNode;

            if (handle.version != ((*versionPtr) & AtomicSafetyHandle.WriteCheck))
            {
                AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut(handle);
            }
            nativeArrayData.safetyHandle = handle;
            return(nativeArrayData);
        }
示例#28
0
        internal unsafe static void Deform(Sprite sprite, Matrix4x4 rootInv, NativeSlice <Vector3> vertices, NativeSlice <Vector4> tangents, NativeSlice <BoneWeight> boneWeights, NativeArray <Matrix4x4> boneTransforms, NativeSlice <Matrix4x4> bindPoses, NativeArray <byte> deformableVertices)
        {
            var verticesFloat3         = vertices.SliceWithStride <float3>();
            var tangentsFloat4         = tangents.SliceWithStride <float4>();
            var bindPosesFloat4x4      = bindPoses.SliceWithStride <float4x4>();
            var spriteVertexCount      = sprite.GetVertexCount();
            var spriteVertexStreamSize = sprite.GetVertexStreamSize();
            var boneTransformsFloat4x4 = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <float4x4>(boneTransforms.GetUnsafePtr(), boneTransforms.Length, Allocator.None);

            byte *deformedPosOffset = (byte *)NativeArrayUnsafeUtility.GetUnsafePtr(deformableVertices);
            NativeSlice <float3> deformableVerticesFloat3 = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <float3>(deformedPosOffset, spriteVertexStreamSize, spriteVertexCount);
            NativeSlice <float4> deformableTangentsFloat4 = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <float4>(deformedPosOffset, spriteVertexStreamSize, 1);   // Just Dummy.

            if (sprite.HasVertexAttribute(Rendering.VertexAttribute.Tangent))
            {
                byte *deformedTanOffset = deformedPosOffset + sprite.GetVertexStreamOffset(Rendering.VertexAttribute.Tangent);
                deformableTangentsFloat4 = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <float4>(deformedTanOffset, spriteVertexStreamSize, spriteVertexCount);
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            var handle1 = CreateSafetyChecks <float4x4>(ref boneTransformsFloat4x4);
            var handle2 = CreateSafetyChecks <float3>(ref deformableVerticesFloat3);
            var handle3 = CreateSafetyChecks <float4>(ref deformableTangentsFloat4);
#endif

            if (sprite.HasVertexAttribute(Rendering.VertexAttribute.Tangent))
            {
                Deform(rootInv, verticesFloat3, tangentsFloat4, boneWeights, boneTransformsFloat4x4, bindPosesFloat4x4, deformableVerticesFloat3, deformableTangentsFloat4);
            }
            else
            {
                Deform(rootInv, verticesFloat3, boneWeights, boneTransformsFloat4x4, bindPosesFloat4x4, deformableVerticesFloat3);
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            DisposeSafetyChecks(handle1);
            DisposeSafetyChecks(handle2);
            DisposeSafetyChecks(handle3);
#endif
        }
        public unsafe void Execute(int index, TransformAccess transform)
        {
            float4x4 rotationTranslationMatrix = new float4x4(transform.rotation, transform.position);
            float4x4 scaleMatrix = float4x4.Scale(transform.localScale);
            float4x4 matrix      = math.mul(rotationTranslationMatrix, scaleMatrix);

            //matrix = float4x4.TRS(transform.position, transform.rotation, new float3(1,1,1));
            //var b = boneTransformOutput.ToNativeSlice();
            for (int i = 0; i < boneTransformOutput.Length; ++i)
            {
                if (index < nativeArraySize[i])
                {
                    var array = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <float4x4>(boneTransformOutput[i].ToPointer(), sizeof(float4x4), nativeArraySize[i]);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref array, nativeArrayNativeSafetyHandles[i]);
#endif
                    array[index] = matrix;
                    break;
                }
                index -= nativeArraySize[i];
            }
        }