Exemplo n.º 1
0
 static Hash128 GetHash128_FromMesh(
     UnityMesh mesh, float4x4 leafToBody,
     ConvexHullGenerationParameters convexHullGenerationParameters = default,
     Material material         = default,
     CollisionFilter filter    = default,
     float4x4 shapeFromBody    = default,
     uint uniqueIdentifier     = default,
     int[] includedIndices     = default,
     float[] blendShapeWeights = default
     )
 {
     // BUG: use TempJob to avoid InvalidOperationException triggered by NativeList.AddRange() inside SpookyHashBuilder
     using (var allIncludedIndices = new NativeList <int>(0, Allocator.TempJob))
         using (var allBlendShapeWeights = new NativeList <float>(0, Allocator.TempJob))
             using (var indices = new NativeArray <int>(includedIndices ?? Array.Empty <int>(), Allocator.TempJob))
                 using (var blendWeights = new NativeArray <float>(blendShapeWeights ?? Array.Empty <float>(), Allocator.TempJob))
                     return(HashableShapeInputs.GetHash128(
                                uniqueIdentifier, convexHullGenerationParameters, material, filter, shapeFromBody,
                                new NativeArray <HashableShapeInputs>(1, Allocator.Temp)
                     {
                         [0] = HashableShapeInputs.FromSkinnedMesh(
                             mesh, leafToBody,
                             indices,
                             allIncludedIndices,
                             blendWeights,
                             allBlendShapeWeights
                             )
                     }, allIncludedIndices, allBlendShapeWeights
                                ));
 }
        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];
                        }
                    }
        }
Exemplo n.º 3
0
        // used to hash convex hull generation properties in a way that is robust to imprecision
        internal static uint GetStableHash(
            this ConvexHullGenerationParameters generationParameters,
            ConvexHullGenerationParameters hashedParameters,
            float tolerance = k_HashFloatTolerance
            )
        {
            var differences = new float3(
                generationParameters.BevelRadius - hashedParameters.BevelRadius,
                generationParameters.MinimumAngle - hashedParameters.MinimumAngle,
                generationParameters.SimplificationTolerance - hashedParameters.SimplificationTolerance
                );

            return(math.cmax(math.abs(differences)) < tolerance
                ? unchecked ((uint)hashedParameters.GetHashCode())
                : unchecked ((uint)generationParameters.GetHashCode()));
        }
Exemplo n.º 4
0
            public void SchedulePreviewIfChanged(PhysicsShapeAuthoring shape)
            {
                using (var currentPoints = new NativeList <float3>(65535, Allocator.Temp))
                {
                    var hash = GetInputHash(
                        shape, currentPoints, m_HashedPoints, m_HashedConvexParameters, out var currentConvexParameters
                        );
                    if (m_InputHash == hash)
                    {
                        return;
                    }

                    m_InputHash = hash;
                    m_HashedConvexParameters = currentConvexParameters;
                    m_HashedPoints.Dispose();
                    m_HashedPoints = new NativeArray <float3>(currentPoints.Length, Allocator.Persistent);
                    m_HashedPoints.CopyFrom(currentPoints);
                }

                if (shape.ShapeType != ShapeType.ConvexHull && shape.ShapeType != ShapeType.Mesh)
                {
                    return;
                }

                // TODO: cache results per input data hash, and simply use existing data (e.g., to make undo/redo faster)
                var output = new NativeArray <BlobAssetReference <Collider> >(1, Allocator.Persistent);

                m_MostRecentlyScheduledJob = shape.ShapeType == ShapeType.Mesh
                    ? ScheduleMeshPreview(shape, output)
                    : ScheduleConvexHullPreview(shape, output);
                m_PreviewJobsOutput.Add(m_MostRecentlyScheduledJob, output);
                if (m_PreviewJobsOutput.Count == 1)
                {
                    CheckPreviewJobsForCompletion();
                    EditorApplication.update    += CheckPreviewJobsForCompletion;
                    EditorApplication.delayCall += () =>
                    {
                        SceneViewUtility.DisplayProgressNotification(
                            Styles.PreviewGenerationNotification, () => float.PositiveInfinity
                            );
                    };
                }
            }
Exemplo n.º 5
0
        public static unsafe Hash128 GetHash128(
            uint uniqueIdentifier,
            ConvexHullGenerationParameters hullGenerationParameters,
            Material material,
            CollisionFilter filter,
            float4x4 bakeFromShape,
            NativeArray <HashableShapeInputs> inputs,
            NativeArray <int> allIncludedIndices,
            NativeArray <float> allBlendShapeWeights,
            float linearPrecision = k_DefaultLinearPrecision
            )
        {
            var numInputs = inputs.IsCreated ? inputs.Length : 0;

            // quantize shape-level transforms
            var bounds = new Aabb {
                Min = float.MaxValue, Max = float.MinValue
            };

            for (int i = 0; i < numInputs; i++)
            {
                var d = inputs[i];
                bounds.Include(math.mul(d.BodyFromShape, new float4(d.Bounds.Min, 1f)).xyz);
                bounds.Include(math.mul(d.BodyFromShape, new float4(d.Bounds.Max, 1f)).xyz);
            }
            GetQuantizedTransformations(bakeFromShape, bounds, out var bakeMatrix, linearPrecision);

            // bakeFromShape only contains scale/shear information, so only the inner 3x3 needs to contribute to the hash
            var scaleShear = new float3x3(bakeMatrix.c0.xyz, bakeMatrix.c1.xyz, bakeMatrix.c2.xyz);

            var bytes = new NativeList <byte>(Allocator.Temp);

            bytes.Append(ref uniqueIdentifier);
            bytes.Append(ref hullGenerationParameters);
            bytes.Append(ref material);
            bytes.Append(ref filter);
            bytes.Append(ref scaleShear);
            bytes.Append(inputs);
            bytes.Append(allIncludedIndices);
            bytes.Append(allBlendShapeWeights);
            return(HashUtility.Hash128(bytes.GetUnsafeReadOnlyPtr(), bytes.Length));
        }
Exemplo n.º 6
0
 internal void RegisterConvexColliderDeferred(
     T shape,
     NativeArray <float3> points,
     ConvexHullGenerationParameters generationParameters,
     CollisionFilter filter, Material material
     )
 {
     m_ConvexShapes.Add(shape);
     m_ConvexColliderJobs.Add(new ConvertConvexColliderInput
     {
         BodyEntity           = GetPrimaryEntity(GetPrimaryBody(shape)),
         LeafEntity           = GetPrimaryEntity(shape),
         CompoundFromChild    = GetCompoundFromChild(shape),
         GenerationParameters = generationParameters,
         PointsStart          = m_ConvexColliderPoints.Length,
         PointCount           = points.Length,
         Filter   = filter,
         Material = material
     });
     m_ConvexColliderPoints.AddRange(points);
 }
Exemplo n.º 7
0
        internal static void GetBakedConvexProperties(
            this PhysicsShapeAuthoring shape, NativeList <float3> pointCloud, out ConvexHullGenerationParameters generationParameters
            )
        {
            shape.GetConvexHullProperties(pointCloud);

            shape.BakePoints(pointCloud);

            // compute convex radius
            var center      = float3.zero;
            var orientation = EulerAngles.Default;
            var bakeToShape =
                GetPrimitiveBakeToShapeMatrix(shape, ref center, ref orientation, 1f, k_DefaultAxisPriority);
            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);
        }
Exemplo n.º 8
0
            unsafe uint GetInputHash(
                PhysicsShapeAuthoring shape,
                NativeList <float3> currentPoints,
                NativeArray <float3> hashedPoints,
                ConvexHullGenerationParameters hashedConvexParameters,
                out ConvexHullGenerationParameters currentConvexProperties
                )
            {
                currentConvexProperties = default;
                switch (shape.ShapeType)
                {
                case ShapeType.ConvexHull:
                    shape.GetBakedConvexProperties(currentPoints, out currentConvexProperties);

                    return(math.hash(
                               new uint3(
                                   (uint)shape.ShapeType,
                                   currentConvexProperties.GetStableHash(hashedConvexParameters),
                                   currentPoints.GetStableHash(hashedPoints)
                                   )
                               ));

                case ShapeType.Mesh:
                    var indices = new NativeList <int>(65535, Allocator.Temp);
                    shape.GetBakedMeshProperties(currentPoints, indices);

                    return(math.hash(
                               new uint3(
                                   (uint)shape.ShapeType,
                                   currentPoints.GetStableHash(hashedPoints),
                                   math.hash(indices.GetUnsafePtr(), UnsafeUtility.SizeOf <int>() * indices.Length)
                                   )
                               ));

                default:
                    return((uint)shape.ShapeType);
                }
            }
    public static BodyInfo CreateBody(GameObject gameObject)
    {
        var bounds        = gameObject.GetComponent <MeshRenderer>().bounds;
        var basicBodyInfo = gameObject.GetComponent <BasicBodyInfo>();
        BlobAssetReference <Unity.Physics.Collider> collider = default;

        switch (basicBodyInfo.Type)
        {
        case BodyType.Sphere:
            float radius = math.cmax(bounds.extents);
            collider = Unity.Physics.SphereCollider.Create(
                new SphereGeometry
            {
                Center = float3.zero,
                Radius = radius
            });
            break;

        case BodyType.Box:
            collider = Unity.Physics.BoxCollider.Create(
                new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = bounds.size,
                BevelRadius = 0.0f
            });
            break;

        case BodyType.ConvexHull:
            var mesh  = gameObject.GetComponent <MeshFilter>().mesh;
            var scale = gameObject.transform.lossyScale;
            NativeArray <float3> points = new NativeArray <float3>(mesh.vertexCount, Allocator.Temp);
            for (int i = 0; i < mesh.vertexCount; i++)
            {
                points[i]  = mesh.vertices[i];
                points[i] *= scale;
            }
            ConvexHullGenerationParameters def = ConvexHullGenerationParameters.Default;
            def.BevelRadius = 0.0f;
            collider        = Unity.Physics.ConvexCollider.Create(
                points, def, CollisionFilter.Default);
            break;

        case BodyType.Capsule:
            var capsuleRadius   = math.cmin(bounds.extents);
            var capsuleLength   = math.cmax(bounds.extents);
            var capsuleGeometry = new CapsuleGeometry
            {
                Radius  = capsuleRadius,
                Vertex0 = new float3(0, capsuleLength - capsuleRadius, 0f),
                Vertex1 = new float3(0, -1.0f * (capsuleLength - capsuleRadius), 0f)
            };
            collider = Unity.Physics.CapsuleCollider.Create(capsuleGeometry);
            break;

        default:
            Assert.IsTrue(false, "Invalid body type");
            break;
        }

        bool isDynamic = !gameObject.GetComponent <BasicBodyInfo>().IsStatic;

        return(new BodyInfo
        {
            Mass = isDynamic ? basicBodyInfo.Mass : 0f,
            Collider = collider,
            AngularVelocity = float3.zero,
            LinearVelocity = float3.zero,
            Orientation = gameObject.transform.rotation,
            Position = gameObject.transform.position,
            IsDynamic = isDynamic
        });
    }
Exemplo n.º 10
0
        public void TestConvexColliderCreateInvalid()
        {
            // Invalid points
            {
                var validBevelRadius = new ConvexHullGenerationParameters {
                    BevelRadius = 0.15f
                };

                // invalid point, +inf
                {
                    var invalidPoints = new NativeArray <float3>(6, Allocator.TempJob)
                    {
                        [0] = new float3(1.45f, 8.67f, 3.45f),
                        [1] = new float3(8.75f, 1.23f, 6.44f),
                        [2] = new float3(float.PositiveInfinity, 5.33f, -2.55f),
                        [3] = new float3(8.76f, 4.56f, -4.54f),
                        [4] = new float3(9.75f, -0.45f, -8.99f),
                        [5] = new float3(7.66f, 3.44f, 0.0f)
                    };
                    TestUtils.ThrowsException <ArgumentException>(
                        () => ConvexCollider.Create(invalidPoints, validBevelRadius, CollisionFilter.Default)
                        );
                    invalidPoints.Dispose();
                }

                // invalid point, -inf
                {
                    var invalidPoints = new NativeArray <float3>(6, Allocator.TempJob)
                    {
                        [0] = new float3(1.45f, 8.67f, 3.45f),
                        [1] = new float3(8.75f, 1.23f, 6.44f),
                        [2] = new float3(float.NegativeInfinity, 5.33f, -2.55f),
                        [3] = new float3(8.76f, 4.56f, -4.54f),
                        [4] = new float3(9.75f, -0.45f, -8.99f),
                        [5] = new float3(7.66f, 3.44f, 0.0f)
                    };
                    TestUtils.ThrowsException <ArgumentException>(
                        () => ConvexCollider.Create(invalidPoints, validBevelRadius, CollisionFilter.Default)
                        );
                    invalidPoints.Dispose();
                }

                // invalid point, NaN
                {
                    var invalidPoints = new NativeArray <float3>(6, Allocator.TempJob)
                    {
                        [0] = new float3(1.45f, 8.67f, 3.45f),
                        [1] = new float3(8.75f, 1.23f, 6.44f),
                        [2] = new float3(float.NaN, 5.33f, -2.55f),
                        [3] = new float3(8.76f, 4.56f, -4.54f),
                        [4] = new float3(9.75f, -0.45f, -8.99f),
                        [5] = new float3(7.66f, 3.44f, 0.0f)
                    };
                    TestUtils.ThrowsException <ArgumentException>(
                        () => ConvexCollider.Create(invalidPoints, validBevelRadius, CollisionFilter.Default)
                        );
                    invalidPoints.Dispose();
                }
            }

            // invalid convex radius
            {
                var points = new NativeArray <float3>(6, Allocator.TempJob)
                {
                    [0] = new float3(1.45f, 8.67f, 3.45f),
                    [1] = new float3(8.75f, 1.23f, 6.44f),
                    [2] = new float3(7.54f, 5.33f, -2.55f),
                    [3] = new float3(8.76f, 4.56f, -4.54f),
                    [4] = new float3(9.75f, -0.45f, -8.99f),
                    [5] = new float3(7.66f, 3.44f, 0.0f)
                };
                float3 scale = new float3(1.0f, 1.0f, 1.0f);
                var    invalidBevelRadius = new ConvexHullGenerationParameters();

                // negative convex radius
                {
                    invalidBevelRadius.BevelRadius = -0.30f;
                    TestUtils.ThrowsException <ArgumentException>(
                        () => ConvexCollider.Create(points, invalidBevelRadius, CollisionFilter.Default)
                        );
                }

                // +inf convex radius
                {
                    invalidBevelRadius.BevelRadius = float.PositiveInfinity;
                    TestUtils.ThrowsException <ArgumentException>(
                        () => ConvexCollider.Create(points, invalidBevelRadius, CollisionFilter.Default)
                        );
                }

                // -inf convex radius
                {
                    invalidBevelRadius.BevelRadius = float.NegativeInfinity;
                    TestUtils.ThrowsException <ArgumentException>(
                        () => ConvexCollider.Create(points, invalidBevelRadius, CollisionFilter.Default)
                        );
                }

                // nan convex radius
                {
                    invalidBevelRadius.BevelRadius = float.NaN;
                    TestUtils.ThrowsException <ArgumentException>(
                        () => ConvexCollider.Create(points, invalidBevelRadius, CollisionFilter.Default)
                        );
                }

                points.Dispose();
            }
        }