Пример #1
0
        internal void CreateCollider(Entity rigidbodyEntity)
        {
            var colliderCount = RigidbodyToColliderMapping.CountValuesForKey(rigidbodyEntity);

            if (colliderCount == 0)
            {
                return;
            }

            // Single collider doesn't require a compound collider.
            if (colliderCount == 1)
            {
                var foundColliderBlob = RigidbodyToColliderMapping.TryGetFirstValue(rigidbodyEntity, out BlobAssetReference <Collider> colliderBlob, out NativeMultiHashMapIterator <Entity> ignore);
                SafetyChecks.IsTrue(foundColliderBlob);

                // Add the single collider to the rigidbody entity.
                DstEntityManager.AddComponentData(rigidbodyEntity, new PhysicsColliderBlob {
                    Collider = colliderBlob
                });

                return;
            }

            // Multiple colliders required a compound collider.
            var childrenArray = new NativeArray <PhysicsCompoundCollider.ColliderBlobInstance>(colliderCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var childIndex    = 0;

            foreach (var colliderBlob in RigidbodyToColliderMapping.GetValuesForKey(rigidbodyEntity))
            {
                childrenArray[childIndex++] = new PhysicsCompoundCollider.ColliderBlobInstance
                {
                    Collider = colliderBlob,
                    // NOTE: Right now the relative pose of the collider with respect to the rigidbody is baked into the shape.
                    // Later, we'll want to remove that and only have its offset (if any) baked into it and use this transform instead.
                    CompoundFromChild = PhysicsTransform.Identity
                };
            }

            // Create the compound collider.
            DstEntityManager.AddComponentData(rigidbodyEntity, new PhysicsColliderBlob {
                Collider = PhysicsCompoundCollider.Create(childrenArray)
            });

            // We've finished with the children blobs and array.
            for (var i = 0; i < colliderCount; ++i)
            {
                childrenArray[i].Collider.Dispose();
            }
            childrenArray.Dispose();
        }
Пример #2
0
        public void MassProperties_BuiltFromChildren_MatchesExpected()
        {
            void TestCompoundBox(PhysicsTransform transform)
            {
                // Create a unit box
                var boxCollider = PhysicsBoxCollider.Create(new BoxGeometry
                {
                    Size        = new float2(1f),
                    Center      = transform.Translation,
                    Angle       = 0f,
                    BevelRadius = 0.0f
                });

                // Create a compound of mini boxes, matching the volume of the single box
                var miniBox = PhysicsBoxCollider.Create(new BoxGeometry
                {
                    Size        = new float2(0.5f),
                    Center      = float2.zero,
                    Angle       = 0f,
                    BevelRadius = 0.0f
                });

                const uint UserData      = 0xDEADBEEF;
                const int  ChildrenCount = 4;

                var childrenTransforms = new NativeArray <PhysicsTransform>(ChildrenCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory)
                {
                    [0] = new PhysicsTransform(new float2(-0.25f, -0.25f), float2x2.identity),
                    [1] = new PhysicsTransform(new float2(0.25f, -0.25f), float2x2.identity),
                    [2] = new PhysicsTransform(new float2(0.25f, 0.25f), float2x2.identity),
                    [3] = new PhysicsTransform(new float2(-0.25f, 0.25f), float2x2.identity),
                };

                var children = new NativeArray <PhysicsCompoundCollider.ColliderBlobInstance>(ChildrenCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

                for (var i = 0; i < ChildrenCount; ++i)
                {
                    children[i] = new PhysicsCompoundCollider.ColliderBlobInstance
                    {
                        Collider          = miniBox,
                        CompoundFromChild = PhysicsMath.mul(transform, childrenTransforms[i])
                    };
                }

                var colliderBlob = PhysicsCompoundCollider.Create(children, UserData);

                childrenTransforms.Dispose();
                children.Dispose();

                ref var collider = ref colliderBlob.GetColliderRef <PhysicsCompoundCollider>();

                Assert.AreEqual(ColliderType.Compound, collider.ColliderType);
                Assert.AreEqual(CollisionType.Composite, collider.CollisionType);
                Assert.AreEqual(UserData, collider.UserData);

                var boxMassProperties      = boxCollider.Value.MassProperties;
                var compoundMassProperties = colliderBlob.Value.MassProperties;

                Assert.AreEqual(boxMassProperties.Area, compoundMassProperties.Area, 1e-3f, "Area incorrect.");
                Assert.AreEqual(boxMassProperties.AngularExpansionFactor, compoundMassProperties.AngularExpansionFactor, 1e-3f, "AngularExpansionFactor incorrect.");
                PhysicsAssert.AreEqual(boxMassProperties.MassDistribution.LocalCenterOfMass, compoundMassProperties.MassDistribution.LocalCenterOfMass, 1e-3f, "LocalCenterOfMass incorrect.");
                Assert.AreEqual(boxMassProperties.MassDistribution.InverseInertia, compoundMassProperties.MassDistribution.InverseInertia, 1e-3f, "InverseInertia incorrect.");

                boxCollider.Dispose();
                colliderBlob.Dispose();
            }