internal static void GetBakedConvexProperties(
            this PhysicsShapeAuthoring shape, NativeList <float3> pointCloud, out ConvexHullGenerationParameters generationParameters,
            out Hash128 hashedInputs
            )
        {
            using (var inputs = new NativeList <HashableShapeInputs>(8, Allocator.TempJob))
                using (var allSkinIndices = new NativeList <int>(4096, Allocator.TempJob))
                    using (var allBlendShapeWeights = new NativeList <float>(64, Allocator.TempJob))
                    {
                        shape.GetConvexHullProperties(pointCloud, true, inputs, allSkinIndices, allBlendShapeWeights);

                        shape.BakePoints(pointCloud);

                        // compute convex radius
                        var center       = float3.zero;
                        var orientation  = EulerAngles.Default;
                        var localToWorld = shape.transform.localToWorldMatrix;
                        var shapeToWorld = shape.GetShapeToWorldMatrix();
                        var bakeToShape  =
                            GetPrimitiveBakeToShapeMatrix(localToWorld, shapeToWorld, ref center, ref orientation, 1f, k_DefaultAxisPriority);
                        using (var aabb = new NativeArray <Aabb>(1, Allocator.TempJob))
                        {
                            new GetAabbJob {
                                Points = pointCloud, Aabb = aabb
                            }.Run();
                            HashableShapeInputs.GetQuantizedTransformations(bakeToShape, aabb[0], out bakeToShape);
                        }
                        var s = new float3(math.length(bakeToShape[0]), math.length(bakeToShape[1]), math.length(bakeToShape[2]));
                        generationParameters = shape.ConvexHullGenerationParameters;
                        generationParameters.SimplificationTolerance = math.max(
                            ConvexHullGenerationParametersExtensions.k_MinRecommendedSimplificationTolerance,
                            math.cmax(s) * generationParameters.SimplificationTolerance
                            );
                        generationParameters.BevelRadius *= math.cmin(s);

                        using (var hash = new NativeArray <Hash128>(1, Allocator.TempJob))
                        {
                            var job = new GetShapeInputsHashJob
                            {
                                Result = hash,
                                ForceUniqueIdentifier = (uint)(shape.ForceUnique ? shape.GetInstanceID() : 0),
                                GenerationParameters  = generationParameters,
                                Material             = shape.GetMaterial(),
                                CollisionFilter      = shape.GetFilter(),
                                BakeFromShape        = shape.GetLocalToShapeMatrix(),
                                Inputs               = inputs,
                                AllSkinIndices       = allSkinIndices,
                                AllBlendShapeWeights = allBlendShapeWeights
                            };
                            job.Run();
                            hashedInputs = hash[0];
                        }
                    }
        }
            public void Execute(int index)
            {
                var shapeData = ComputationData[index];

                var material        = shapeData.Material;
                var collisionFilter = shapeData.CollisionFilter;
                var shapeType       = shapeData.ShapeType;

                var builder = new SpookyHashBuilder(Allocator.Temp);

                builder.Append(ref shapeType);
                builder.Append(ref shapeData.ForceUniqueIdentifier);
                builder.Append(ref collisionFilter);
                builder.Append(ref material);

                switch (shapeType)
                {
                case ShapeType.Box:
                {
                    var p = shapeData.BoxProperties;
                    builder.Append(ref p);
                    var aabb = RotatedBoxAabb(p.Center, p.Size, shapeData.BoxProperties.Orientation);
                    HashableShapeInputs.GetQuantizedTransformations(shapeData.BodyFromShape, aabb, out var transformations);
                    builder.Append(ref transformations);
                    break;
                }

                case ShapeType.Capsule:
                {
                    var p = shapeData.CapsuleProperties;
                    builder.Append(ref p);
                    var v0   = p.Vertex0;
                    var v1   = p.Vertex1;
                    var r    = p.Radius;
                    var aabb = RotatedCylinderAabb(p.GetCenter(), p.GetHeight(), r, quaternion.LookRotationSafe(v0 - v1, math.up()));
                    HashableShapeInputs.GetQuantizedTransformations(shapeData.BodyFromShape, aabb, out var transformations);
                    builder.Append(ref transformations);
                    break;
                }

                case ShapeType.Cylinder:
                {
                    var p = shapeData.CylinderProperties;
                    builder.Append(ref p);
                    var aabb = RotatedCylinderAabb(p.Center, p.Height, p.Radius, shapeData.CylinderProperties.Orientation);
                    HashableShapeInputs.GetQuantizedTransformations(shapeData.BodyFromShape, aabb, out var transformations);
                    builder.Append(ref transformations);
                    break;
                }

                case ShapeType.Plane:
                {
                    var v = shapeData.PlaneVertices;
                    builder.Append(ref v);
                    var planeCenter = math.lerp(v.c0, v.c2, 0.5f);
                    var planeSize   = math.abs(v.c0 - v.c2);
                    var aabb        = RotatedBoxAabb(planeCenter, planeSize, quaternion.LookRotationSafe(v.c1 - v.c2, math.cross(v.c1 - v.c0, v.c2 - v.c1)));
                    HashableShapeInputs.GetQuantizedTransformations(shapeData.BodyFromShape, aabb, out var transformations);
                    builder.Append(ref transformations);
                    break;
                }

                case ShapeType.Sphere:
                {
                    var p = shapeData.SphereProperties;
                    builder.Append(ref p);
                    var aabb = new Aabb {
                        Min = p.Center - new float3(p.Radius), Max = p.Center + new float3(p.Radius)
                    };
                    HashableShapeInputs.GetQuantizedTransformations(shapeData.BodyFromShape, aabb, out var transformations);
                    builder.Append(ref transformations);
                    break;
                }

                case ShapeType.ConvexHull:
                {
                    Hashes[index] = shapeData.Instance.Hash;     // precomputed when gathering inputs
                    return;
                }

                case ShapeType.Mesh:
                {
                    Hashes[index] = shapeData.Instance.Hash;     // precomputed when gathering inputs
                    return;
                }
                }

                Hashes[index] = builder.Finish();
            }