예제 #1
0
        public unsafe void PhysicsBodyCalculateDistancePointTest()
        {
            var geometry = new BoxGeometry
            {
                Size = new float2(1f),
            };

            using (var collider = PhysicsBoxCollider.Create(geometry))
            {
                var physicsBody = new PhysicsBody(collider);

                var queryInput = new PointDistanceInput
                {
                    Position = new float2(-10f),
                    Filter   = CollisionFilter.Default
                };

                var closestHit = new DistanceHit();
                var allHits    = new NativeList <DistanceHit>(Allocator.Temp);

                // OK case : with enough max distance
                queryInput.MaxDistance = 10000.0f;
                Assert.IsTrue(physicsBody.CalculateDistance(queryInput));
                Assert.IsTrue(physicsBody.CalculateDistance(queryInput, out closestHit));
                Assert.IsTrue(physicsBody.CalculateDistance(queryInput, ref allHits));

                // Fail case : not enough max distance
                queryInput.MaxDistance = 1;
                Assert.IsFalse(physicsBody.CalculateDistance(queryInput));
                Assert.IsFalse(physicsBody.CalculateDistance(queryInput, out closestHit));
                Assert.IsFalse(physicsBody.CalculateDistance(queryInput, ref allHits));

                allHits.Dispose();
            }
        }
예제 #2
0
            public TestBox(BoxGeometry geometry, float3 translation, quaternion rotation)
            {
                Entity = EntityManager.CreateEntity(
                    typeof(PhysicsColliderBlob),
                    typeof(LocalToWorld)
                    );

                Geometry = geometry;

                PhysicsTransform = new PhysicsTransform(translation, rotation);
                Translation      = translation;
                Rotation         = rotation;

                var colliderBlob = PhysicsBoxCollider.Create(Geometry);

                Aabb = colliderBlob.Value.CalculateAabb(PhysicsTransform);

                EntityManager.AddComponentData(
                    Entity,
                    new PhysicsColliderBlob {
                    Collider = colliderBlob
                }
                    );

                EntityManager.AddComponentData(
                    Entity,
                    new LocalToWorld {
                    Value = new float4x4(rotation, translation)
                }
                    );
            }
예제 #3
0
        public void TestPhysicsBoxColliderCreate()
        {
            var geometry = new BoxGeometry
            {
                Size        = new float2(0.01f, 120.40f),
                Center      = new float2(-10.10f, 10.12f),
                Angle       = 0f,
                BevelRadius = 0f
            };

            const uint UserData = 0xDEADBEEF;

            using (var colliderBlob = PhysicsBoxCollider.Create(geometry, CollisionFilter.Default, PhysicsMaterial.Default, UserData))
            {
                ref var collider = ref colliderBlob.GetColliderRef <PhysicsBoxCollider>();

                Assert.AreEqual(ColliderType.Box, collider.ColliderType);
                Assert.AreEqual(CollisionType.Convex, collider.CollisionType);
                Assert.AreEqual(UserData, collider.UserData);
                Assert.AreEqual(CollisionFilter.Default, collider.Filter);
                Assert.AreEqual(PhysicsMaterial.Default, collider.Material);

                Assert.AreEqual(geometry.Size, collider.Size);
                Assert.AreEqual(geometry.Size, collider.Geometry.Size);
                Assert.AreEqual(geometry.Center, collider.Center);
                Assert.AreEqual(geometry.Center, collider.Geometry.Center);
                Assert.AreEqual(geometry.Angle, collider.Angle);
                Assert.AreEqual(geometry.Angle, collider.Geometry.Angle);
                Assert.AreEqual(geometry.BevelRadius, collider.BevelRadius);
                Assert.AreEqual(geometry.BevelRadius, collider.Geometry.BevelRadius);
            }
예제 #4
0
        public unsafe void PhysicsBodyOverlapPointTest()
        {
            var geometry = new BoxGeometry
            {
                Size = new float2(2f),
            };

            using (var collider = PhysicsBoxCollider.Create(geometry))
            {
                var physicsBody = new PhysicsBody(collider);

                var queryInput = new OverlapPointInput()
                {
                    Filter = CollisionFilter.Default
                };
                var closestHit = new OverlapPointHit();
                var allHits    = new NativeList <OverlapPointHit>(Allocator.Temp);

                // OK case.
                var positionOK = new float2(1f);
                queryInput.Position = positionOK;
                Assert.IsTrue(physicsBody.OverlapPoint(queryInput));
                Assert.IsTrue(physicsBody.OverlapPoint(queryInput, out closestHit));
                Assert.IsTrue(physicsBody.OverlapPoint(queryInput, ref allHits));

                // Fail Case.
                var positionFail = new float2(-10f);
                queryInput.Position = positionFail;
                Assert.IsFalse(physicsBody.OverlapPoint(queryInput));
                Assert.IsFalse(physicsBody.OverlapPoint(queryInput, out closestHit));
                Assert.IsFalse(physicsBody.OverlapPoint(queryInput, ref allHits));

                allHits.Dispose();
            }
        }
예제 #5
0
        // Adds a dynamic box to the world
        private unsafe void AddDynamicBoxToWorld(ref PhysicsWorld physicsWorld, int index, BoxGeometry geometry)
        {
            Assert.IsTrue(index < physicsWorld.DynamicBodyCount, "Dynamic body index is out of range in AddDynamicBoxToWorld");

            var bodies      = physicsWorld.DynamicBodies;
            var physicsBody = bodies[index];

            var colliderBlob = PhysicsBoxCollider.Create(geometry);

            physicsBody.SetCollider(colliderBlob);
            m_ColliderBlobs.Add(colliderBlob);

            bodies[index] = physicsBody;
        }
예제 #6
0
        public unsafe void PhysicsBodyCastColliderTest()
        {
            var geometry = new BoxGeometry
            {
                Size = new float2(1f),
            };

            using (var collider = PhysicsBoxCollider.Create(geometry))
            {
                var physicsBody = new PhysicsBody(collider);

                var queryInput = new ColliderCastInput()
                {
                    Rotation = float2x2.identity
                };
                var closestHit = new ColliderCastHit();
                var allHits    = new NativeList <ColliderCastHit>(Allocator.Temp);

                var circleGeometry = new CircleGeometry {
                    Radius = 0.5f
                };

                using (var circleBlob = PhysicsCircleCollider.Create(circleGeometry))
                {
                    queryInput.Collider = circleBlob;

                    // OK case.
                    var startOK = new float2(-10f, -10f);
                    var endOK   = new float2(10f, 10f);
                    queryInput.Start = startOK;
                    queryInput.End   = endOK;
                    Assert.IsTrue(physicsBody.CastCollider(queryInput));
                    Assert.IsTrue(physicsBody.CastCollider(queryInput, out closestHit));
                    Assert.IsTrue(physicsBody.CastCollider(queryInput, ref allHits));

                    // Fail Case.
                    var startFail = new float2(-10f, -10f);
                    var endFail   = new float2(10f, -10f);
                    queryInput.Start = startFail;
                    queryInput.End   = endFail;
                    Assert.IsFalse(physicsBody.CastCollider(queryInput));
                    Assert.IsFalse(physicsBody.CastCollider(queryInput, out closestHit));
                    Assert.IsFalse(physicsBody.CastCollider(queryInput, ref allHits));
                }

                allHits.Dispose();
            }
        }
예제 #7
0
        protected override void OnUpdate()
        {
            Entities.ForEach((UnityEngine.BoxCollider2D collider) =>
            {
                // Convert the collider if it's valid.
                if (ConversionUtilities.CanConvertCollider(collider))
                {
                    try
                    {
                        var lossyScale = new float3(collider.transform.lossyScale).xy;
                        if (math.any(!math.isfinite(lossyScale)) || math.any(lossyScale <= 0.0f))
                        {
                            throw new ArgumentException("Transform XY scale cannot be zero or Infinite/NaN.", "Transform XY scale.");
                        }

                        var localToWorld = ConversionUtilities.GetColliderLocalToWorld(collider);
                        var size         = collider.size;

                        var geometry = new BoxGeometry
                        {
                            Center      = new float3(localToWorld.MultiplyPoint(collider.offset)).xy,
                            Size        = new float2(size.x * lossyScale.x, size.y * lossyScale.y),
                            Angle       = PhysicsMath.ZRotationFromQuaternion(localToWorld.rotation),
                            BevelRadius = math.max(collider.edgeRadius, PhysicsSettings.Constants.MinimumConvexRadius),
                        };

                        geometry.Validate();

                        var colliderBlob = PhysicsBoxCollider.Create(
                            geometry,
                            ConversionUtilities.GetCollisionFilterFromCollider(collider),
                            ConversionUtilities.GetPhysicsMaterialFromCollider(collider)
                            );

                        // Submit the collider for conversion.
                        m_ColliderConversionSystem.SubmitCollider(collider, ref colliderBlob);
                    }
                    catch (ArgumentException exception)
                    {
                        UnityEngine.Debug.LogWarning($"{collider.name}: {exception.Message}", collider);
                    }
                }
            });
        }
예제 #8
0
        public unsafe void PhysicsBodyOverlapColliderTest()
        {
            var geometry = new BoxGeometry
            {
                Size = new float2(2f),
            };

            using (var collider = PhysicsBoxCollider.Create(geometry))
            {
                var physicsBody = new PhysicsBody(collider);

                var queryInput = new OverlapColliderInput()
                {
                    Filter = CollisionFilter.Default
                };
                var closestHit = new OverlapColliderHit();
                var allHits    = new NativeList <OverlapColliderHit>(Allocator.Temp);

                var circleGeometry = new CircleGeometry {
                    Radius = 0.5f
                };
                using (var circleBlob = PhysicsCircleCollider.Create(circleGeometry))
                {
                    queryInput.Collider = circleBlob;

                    // OK case.
                    var transformOK = new PhysicsTransform(new float2(1f));
                    queryInput.Transform = transformOK;
                    Assert.IsTrue(physicsBody.OverlapCollider(queryInput));
                    Assert.IsTrue(physicsBody.OverlapCollider(queryInput, out closestHit));
                    Assert.IsTrue(physicsBody.OverlapCollider(queryInput, ref allHits));

                    // Fail Case.
                    var transformFail = new PhysicsTransform(new float2(-10f));
                    queryInput.Transform = transformFail;
                    Assert.IsFalse(physicsBody.OverlapCollider(queryInput));
                    Assert.IsFalse(physicsBody.OverlapCollider(queryInput, out closestHit));
                    Assert.IsFalse(physicsBody.OverlapCollider(queryInput, ref allHits));
                }

                allHits.Dispose();
            }
        }
예제 #9
0
        public unsafe void PhysicsBodyCalculateDistanceTest()
        {
            var geometry = new BoxGeometry
            {
                Size = new float2(1f),
            };

            using (var collider = PhysicsBoxCollider.Create(geometry))
            {
                var physicsBody = new PhysicsBody(collider);

                var circleGeometry = new CircleGeometry {
                    Radius = 1f
                };

                using (var circleBlob = PhysicsCircleCollider.Create(circleGeometry))
                {
                    var queryInput = new ColliderDistanceInput
                    {
                        Collider  = circleBlob,
                        Transform = new PhysicsTransform(new float2(-10f))
                    };

                    var closestHit = new DistanceHit();
                    var allHits    = new NativeList <DistanceHit>(Allocator.Temp);

                    // OK case : with enough max distance
                    queryInput.MaxDistance = 10000.0f;
                    Assert.IsTrue(physicsBody.CalculateDistance(queryInput));
                    Assert.IsTrue(physicsBody.CalculateDistance(queryInput, out closestHit));
                    Assert.IsTrue(physicsBody.CalculateDistance(queryInput, ref allHits));

                    // Fail case : not enough max distance
                    queryInput.MaxDistance = 1f;
                    Assert.IsFalse(physicsBody.CalculateDistance(queryInput));
                    Assert.IsFalse(physicsBody.CalculateDistance(queryInput, out closestHit));
                    Assert.IsFalse(physicsBody.CalculateDistance(queryInput, ref allHits));

                    allHits.Dispose();
                }
            }
        }
예제 #10
0
        public void PhysicsBodyCalculateAabb_BoxColliderTest()
        {
            var geometry = new BoxGeometry
            {
                Size        = 1.0f,
                BevelRadius = 0.2f
            };

            var collider1 = PhysicsBoxCollider.Create(geometry);
            var collider2 = PhysicsBoxCollider.Create(geometry);

            var physicsBody = new PhysicsBody(collider1);

            var aabb = physicsBody.CalculateAabb();

            Assert.IsTrue(aabb.Equals(collider2.Value.CalculateAabb()));

            collider1.Dispose();
            collider2.Dispose();
        }
예제 #11
0
        public unsafe void PhysicsBodyCastRayTest()
        {
            var geometry = new BoxGeometry
            {
                Size = new float2(1f),
            };

            using (var collider = PhysicsBoxCollider.Create(geometry))
            {
                var physicsBody = new PhysicsBody(collider);

                var queryInput = new RaycastInput()
                {
                    Filter = CollisionFilter.Default
                };
                var closestHit = new RaycastHit();
                var allHits    = new NativeList <RaycastHit>(Allocator.Temp);

                // OK case.
                var startOK = new float2(-10f, -10f);
                var endOK   = new float2(10f, 10f);
                queryInput.Start = startOK;
                queryInput.End   = endOK;
                Assert.IsTrue(physicsBody.CastRay(queryInput));
                Assert.IsTrue(physicsBody.CastRay(queryInput, out closestHit));
                Assert.IsTrue(physicsBody.CastRay(queryInput, ref allHits));

                // Fail Case.
                var startFail = new float2(-10f, -10f);
                var endFail   = new float2(-20f, -20f);
                queryInput.Start = startFail;
                queryInput.End   = endFail;
                Assert.IsFalse(physicsBody.CastRay(queryInput));
                Assert.IsFalse(physicsBody.CastRay(queryInput, out closestHit));
                Assert.IsFalse(physicsBody.CastRay(queryInput, ref allHits));

                allHits.Dispose();
            }
        }
예제 #12
0
        public void RotatedColliderCast_Against_RotatedBox_Test(
            [Values(0f, 10f, -20f, 30f, 40f)] float startX)
        {
            // Simulate the physics.
            SimulatePhysics();

            var aabb = RotatedBox.Aabb;

            Assert.IsTrue(startX < aabb.Min.x);

            var start            = new float2(startX, 0f);
            var expectedPosition = new float2(aabb.Min.x + ColliderEpsilon, 0f);

            // Set-up the query.
            var geometry = new BoxGeometry {
                Size = new float2(BoxSize)
            };

            using (var colliderBlob = PhysicsBoxCollider.Create(geometry, CollisionFilter.Default, PhysicsMaterial.Default))
            {
                var input = new ColliderCastInput
                {
                    Start = start,
                    End   = expectedPosition,

                    Rotation = float2x2.Rotate(math.radians(BoxRotation)),
                    Collider = colliderBlob
                };

                // Perform the query.
                var results = PhysicsWorld.CastCollider(input, out ColliderCastHit hit);
                Assert.IsTrue(results);
                Assert.IsTrue(hit.PhysicsBodyIndex != PhysicsBody.Constants.InvalidBodyIndex, "PhysicsBody Index is Invalid.");
                Assert.AreEqual(hit.Entity, RotatedBox.Entity, "Entity is invalid.");
                PhysicsAssert.AreEqual(expectedPosition, hit.Position, QueryEpsilon, "Hit position is incorrect.");
            }
        }
예제 #13
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();
            }
예제 #14
0
 public void Execute() =>
 PhysicsBoxCollider.Create(new BoxGeometry {
     Size = new float2(1f), Center = float2.zero, Angle = 0f
 }).Dispose();