internal static void UpdateBounds(this SpriteSkin spriteSkin, Matrix4x4 worldToLocal, Matrix4x4 rootLocalToWorld)
        {
            //var worldToLocal = spriteSkin.transform.worldToLocalMatrix;
            //var rootLocalToWorld = spriteSkin.rootBone.localToWorldMatrix;
            var unityBounds = spriteSkin.bounds;
            var matrix      = math.mul(worldToLocal, rootLocalToWorld);
            var center      = new float4(unityBounds.center, 1);
            var extents     = new float4(unityBounds.extents, 0);
            var p0          = math.mul(matrix, center + new float4(-extents.x, -extents.y, extents.z, extents.w));
            var p1          = math.mul(matrix, center + new float4(-extents.x, extents.y, extents.z, extents.w));
            var p2          = math.mul(matrix, center + extents);
            var p3          = math.mul(matrix, center + new float4(extents.x, -extents.y, extents.z, extents.w));
            var min         = math.min(p0, math.min(p1, math.min(p2, p3)));
            var max         = math.max(p0, math.max(p1, math.max(p2, p3)));

            extents = (max - min) * 0.5f;
            center  = min + extents;
            var newBounds = new Bounds()
            {
                center  = new Vector3(center.x, center.y, center.z),
                extents = new Vector3(extents.x, extents.y, extents.z)
            };

            InternalEngineBridge.SetLocalAABB(spriteSkin.spriteRenderer, newBounds);
        }
        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;
        }
Beispiel #3
0
        internal static void Bake(this SpriteSkin spriteSkin, ref NativeArray <byte> deformVertexData)
        {
            if (!spriteSkin.isValid)
            {
                throw new Exception("Bake error: invalid SpriteSkin");
            }

            var sprite = spriteSkin.spriteRenderer.sprite;
            var boneTransformsArray = spriteSkin.boneTransforms;

            Deform(sprite, Matrix4x4.identity, boneTransformsArray, ref deformVertexData);
        }
Beispiel #4
0
        internal static int CalculateTransformHash(this SpriteSkin spriteSkin)
        {
            int bits = 0;
            int boneTransformHash = GetHash(spriteSkin.transform.localToWorldMatrix) >> bits;

            bits++;
            foreach (var transform in spriteSkin.boneTransforms)
            {
                boneTransformHash ^= GetHash(transform.localToWorldMatrix) >> bits;
                bits = (bits + 1) % 8;
            }
            return(boneTransformHash);
        }
Beispiel #5
0
        internal static SpriteSkinValidationResult Validate(this SpriteSkin spriteSkin)
        {
            if (spriteSkin.spriteRenderer.sprite == null)
            {
                return(SpriteSkinValidationResult.SpriteNotFound);
            }

            var bindPoses = spriteSkin.spriteRenderer.sprite.GetBindPoses();

            if (bindPoses.Length == 0)
            {
                return(SpriteSkinValidationResult.SpriteHasNoSkinningInformation);
            }

            if (spriteSkin.rootBone == null)
            {
                return(SpriteSkinValidationResult.RootTransformNotFound);
            }

            if (spriteSkin.boneTransforms == null)
            {
                return(SpriteSkinValidationResult.InvalidTransformArray);
            }

            if (bindPoses.Length != spriteSkin.boneTransforms.Length)
            {
                return(SpriteSkinValidationResult.InvalidTransformArrayLength);
            }

            var rootFound = false;

            foreach (var boneTransform in spriteSkin.boneTransforms)
            {
                if (boneTransform == null)
                {
                    return(SpriteSkinValidationResult.TransformArrayContainsNull);
                }

                if (boneTransform == spriteSkin.rootBone)
                {
                    rootFound = true;
                }
            }

            if (!rootFound)
            {
                return(SpriteSkinValidationResult.RootNotFoundInTransformArray);
            }

            return(SpriteSkinValidationResult.Ready);
        }
Beispiel #6
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);
        }
Beispiel #7
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();
        }
Beispiel #8
0
        internal static void CreateBoneHierarchy(this SpriteSkin spriteSkin)
        {
            if (spriteSkin.spriteRenderer.sprite == null)
            {
                throw new InvalidOperationException("SpriteRenderer has no Sprite set");
            }

            var       spriteBones = spriteSkin.spriteRenderer.sprite.GetBones();
            var       transforms  = new Transform[spriteBones.Length];
            Transform root        = null;

            for (int i = 0; i < spriteBones.Length; ++i)
            {
                CreateGameObject(i, spriteBones, transforms, spriteSkin.transform);
                if (spriteBones[i].parentId < 0 && root == null)
                {
                    root = transforms[i];
                }
            }

            spriteSkin.rootBone       = root;
            spriteSkin.boneTransforms = transforms;
        }
Beispiel #9
0
        internal static void ResetBindPose(this SpriteSkin spriteSkin)
        {
            if (!spriteSkin.isValid)
            {
                throw new InvalidOperationException("SpriteSkin is not valid");
            }

            var spriteBones    = spriteSkin.spriteRenderer.sprite.GetBones();
            var boneTransforms = spriteSkin.boneTransforms;

            for (int i = 0; i < boneTransforms.Length; ++i)
            {
                var boneTransform = boneTransforms[i];
                var spriteBone    = spriteBones[i];

                if (spriteBone.parentId != -1)
                {
                    boneTransform.localPosition = spriteBone.position;
                    boneTransform.localRotation = spriteBone.rotation;
                    boneTransform.localScale    = Vector3.one;
                }
            }
        }
        //TODO: Add other ways to find the transforms in case the named path fails
        internal static void Rebind(this SpriteSkin spriteSkin)
        {
            if (spriteSkin.spriteRenderer.sprite == null)
            {
                throw new ArgumentException("SpriteRenderer has no Sprite set");
            }
            if (spriteSkin.rootBone == null)
            {
                throw new ArgumentException("SpriteSkin has no rootBone");
            }

            var spriteBones    = spriteSkin.spriteRenderer.sprite.GetBones();
            var boneTransforms = new List <Transform>();

            for (int i = 0; i < spriteBones.Length; ++i)
            {
                var boneTransformPath = CalculateBoneTransformPath(i, spriteBones);
                var boneTransform     = spriteSkin.rootBone.Find(boneTransformPath);

                boneTransforms.Add(boneTransform);
            }

            spriteSkin.boneTransforms = boneTransforms.ToArray();
        }