Beispiel #1
0
        public void GetCapsuleProperties_WhenPointsAndOrientationNotIdentity_OrientationPointsDownAxisOfCompositeRotation()
        {
            var capsule = new CapsuleGeometry
            {
                Vertex0 = math.normalizesafe(new float3(-1f, -1f, 0f)),
                Vertex1 = math.normalizesafe(new float3(1f, 1f, 0f))
            };
            var orientation = quaternion.AxisAngle(new float3 {
                z = 1f
            }, math.PI / 4f);

            m_Shape.SetCapsule(capsule, orientation);

            m_Shape.GetCapsuleProperties(out orientation);

            var lookVector         = math.mul(orientation, new float3(0f, 0f, 1f));
            var expectedLookVector = new float3 {
                y = 1f
            };

            Assert.That(
                math.dot(lookVector, expectedLookVector), Is.EqualTo(1f).Within(k_Tolerance),
                $"Expected {expectedLookVector} but got {lookVector}"
                );
        }
Beispiel #2
0
        // TODO: Remove GetCapsuleProperties_WhenPointsAndOrientationNotIdentity_OrientationPointsDownAxisOfCompositeRotation()
        public void SetCapsule(CapsuleGeometry geometry, quaternion orientation)
        {
            var geometryAuthoring = geometry.ToAuthoring();

            geometryAuthoring.Orientation = math.mul(orientation, quaternion.LookRotationSafe(geometry.Vertex1 - geometry.Vertex0, math.up()));
            SetCapsule(geometryAuthoring);
        }
 internal static CapsuleGeometry BakeToBodySpace(
     this CapsuleGeometry capsule, float4x4 localToWorld, float4x4 shapeToWorld,
     out float3 center, out float height, ref EulerAngles orientation
     )
 {
     using (var geometry = new NativeArray <CapsuleGeometry>(1, Allocator.TempJob)
     {
         [0] = capsule
     })
         using (var outCenter = new NativeArray <float3>(1, Allocator.TempJob))
             using (var outHeight = new NativeArray <float>(1, Allocator.TempJob))
                 using (var outOrientation = new NativeArray <EulerAngles>(1, Allocator.TempJob)
                 {
                     [0] = orientation
                 })
                 {
                     var job = new BakeCapsuleJob
                     {
                         Capsule      = geometry,
                         Center       = outCenter,
                         Height       = outHeight,
                         Orientation  = outOrientation,
                         localToWorld = localToWorld,
                         shapeToWorld = shapeToWorld
                     };
                     job.Run();
                     center      = outCenter[0];
                     height      = outHeight[0];
                     orientation = outOrientation[0];
                     return(geometry[0]);
                 }
 }
Beispiel #4
0
        public void TestPhysicsCapsuleColliderCalculateAabbLocalTranslation()
        {
            {
                var geometry = new CapsuleGeometry
                {
                    Vertex0 = new float2(-23f, -2f),
                    Vertex1 = new float2(2.1f, 3f),
                    Radius  = 1.5f
                };

                Aabb expectedAabb = new Aabb
                {
                    Min = new float2(-24.5f, -3.5f),
                    Max = new  float2(3.6f, 4.5f)
                };

                using (var colliderBlob = PhysicsCapsuleCollider.Create(geometry))
                {
                    var aabb = colliderBlob.Value.CalculateAabb();

                    Assert.AreEqual(expectedAabb.Min, aabb.Min);
                    Assert.AreEqual(expectedAabb.Max, aabb.Max);
                }
            }
        }
    private static PhysicsCollider CreateCapsuleCollider(float bottomPoint, float topPoint, float radius, CollisionFilter filter, PhysicsMaterial physicsMaterial)
    {
        CapsuleGeometry capsuleGeo = new CapsuleGeometry
        {
            Vertex0 = new float3(0f, bottomPoint, 0f),
            Vertex1 = new float3(0f, topPoint, 0f),
            Radius  = radius
        };

        return(new PhysicsCollider {
            Value = CapsuleCollider.Create(capsuleGeo, filter, physicsMaterial)
        });
    }
Beispiel #6
0
    protected override void Setup()
    {
        base.Setup();

        m_BoxGeometry = new BoxGeometry
        {
            Size   = new float2(0.01f, 120.40f),
            Center = new float2(-10.10f, 10.12f),
        };

        m_CapsuleGeometry = new CapsuleGeometry
        {
            Vertex0 = new float2(0f, 3f),
            Vertex1 = new float2(0f, -2f),
            Radius  = 1.5f
        };

        m_CircleGeometry = new CircleGeometry
        {
            Center = new float2(-10.10f, 10.12f),
            Radius = 3.0f
        };

        m_Vertices = new NativeArray <float2>(
            new float2[]
        {
            new float2(-1f, -2f),
            new float2(2f, -3f),
            new float2(4f, 5f),
            new float2(-6f, 7f)
        },
            Allocator.Persistent
            );

        m_GiftWrappedIndices = new NativeArray <int>(
            new int[]
        {
            2, 3, 0, 1
        },
            Allocator.Persistent
            );

        Assert.IsTrue(m_Vertices.Length >= 3, "Test array must contain at least 3 points.");
        Assert.AreEqual(m_Vertices.Length, m_GiftWrappedIndices.Length, "Test array lengths do not match.");

        m_PolygonGeometry = new PolygonGeometry
        {
            Vertices    = m_Vertices,
            BevelRadius = 0.0f
        };
    }
Beispiel #7
0
        public void SetCapsule(float3 center, float height, float radius, quaternion orientation)
        {
            var euler = m_PrimitiveOrientation;

            euler.SetValue(orientation);
            var capsule = new CapsuleGeometry
            {
                Vertex0 = new float3(0f, 0f, -0.5f * height),
                Vertex1 = new float3(0f, 0f, 0.5f * height),
                Radius  = radius
            };

            SetCapsule(capsule, euler);
        }
Beispiel #8
0
        private static void CreateCapsules(Scene scene, Material material)
        {
            for (int i = 0; i < 10; i++)
            {
                var rigidActor = scene.Physics.CreateRigidDynamic();

                var capsuleGeom = new CapsuleGeometry(radius: 2, halfHeight: 2);
                var boxShape    = rigidActor.CreateShape(capsuleGeom, material);

                rigidActor.GlobalPose = Matrix4x4.CreateTranslation(0, 30 + i * (capsuleGeom.HalfHeight + capsuleGeom.Radius + 0.5f), 0);
                rigidActor.SetMassAndUpdateInertia(10);

                scene.AddActor(rigidActor);
            }
        }
Beispiel #9
0
		private static void CreateCapsules(Scene scene, Material material)
		{
			for (int i = 0; i < 10; i++)
			{
				var rigidActor = scene.Physics.CreateRigidDynamic();

				var capsuleGeom = new CapsuleGeometry(radius: 2, halfHeight: 2);
				var boxShape = rigidActor.CreateShape(capsuleGeom, material);

				rigidActor.GlobalPose = Matrix.Translation(0, 30 + i * (capsuleGeom.HalfHeight + capsuleGeom.Radius + 0.5f), 0);
				rigidActor.SetMassAndUpdateInertia(10);

				scene.AddActor(rigidActor);
			}
		}
Beispiel #10
0
        public void TestPhysicsCapsuleColliderMassProperties()
        {
            var geometry = new CapsuleGeometry
            {
                Vertex0 = new float2(0f, -2f),
                Vertex1 = new float2(0f, 3f),
                Radius  = 1.5f
            };

            const uint UserData = 0xDEADBEEF;

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

                Assert.AreEqual(ColliderType.Capsule, 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);

                // The following assumptions are made for the MassProperties:
                var radiusSqr   = geometry.Radius * geometry.Radius;
                var bodyLength  = math.distance(geometry.Vertex0, geometry.Vertex1);
                var bodyArea    = bodyLength * geometry.Radius * 2.0f;
                var bodyMass    = bodyArea;
                var bodyInertia = bodyMass * (bodyLength * bodyLength + radiusSqr) / 12.0f;

                var capsArea    = math.PI * radiusSqr;
                var capsMass    = capsArea;
                var capsInertia = capsMass * (0.5f * radiusSqr + bodyLength * bodyLength * 0.25f);

                var mass = bodyMass + capsArea;
                var localCenterOfMass = 0.5f * (geometry.Vertex0 + geometry.Vertex1);
                var area    = bodyArea + capsArea;
                var inertia = bodyInertia + capsInertia + mass * math.dot(localCenterOfMass, localCenterOfMass);
                var angularExpansionFactor = math.length(geometry.Vertex1 - geometry.Vertex0) * 0.5f;

                var massProperties = collider.MassProperties;
                Assert.AreEqual(localCenterOfMass, massProperties.MassDistribution.LocalCenterOfMass);
                Assert.AreEqual(1.0f / inertia, massProperties.MassDistribution.InverseInertia);
                Assert.AreEqual(area, massProperties.Area);
                Assert.AreEqual(angularExpansionFactor, massProperties.AngularExpansionFactor);
            }
 unsafe public void TestCapsuleColliderCreate()
 {
     var geometry = new CapsuleGeometry
     {
         Vertex0 = new float3(1.45f, 0.34f, -8.65f),
         Vertex1 = new float3(100.45f, -80.34f, -8.65f),
         Radius = 1.45f
     };
     var collider = CapsuleCollider.Create(geometry);
     var capsuleCollider = UnsafeUtility.AsRef<CapsuleCollider>(collider.GetUnsafePtr());
     Assert.AreEqual(ColliderType.Capsule, capsuleCollider.Type);
     Assert.AreEqual(CollisionType.Convex, capsuleCollider.CollisionType);
     TestUtils.AreEqual(geometry.Vertex0, capsuleCollider.Vertex0);
     TestUtils.AreEqual(geometry.Vertex0, capsuleCollider.Geometry.Vertex0);
     TestUtils.AreEqual(geometry.Vertex1, capsuleCollider.Vertex1);
     TestUtils.AreEqual(geometry.Vertex1, capsuleCollider.Geometry.Vertex1);
     TestUtils.AreEqual(geometry.Radius, capsuleCollider.Radius);
     TestUtils.AreEqual(geometry.Radius, capsuleCollider.Geometry.Radius);
 }
            public void Execute()
            {
                var radius      = Capsule[0].Radius;
                var center      = Capsule[0].GetCenter();
                var height      = Capsule[0].GetHeight();
                var orientation = Orientation[0];

                var s             = new float3(radius * 2f, radius * 2f, height);
                var basisToWorld  = GetBasisToWorldMatrix(localToWorld, center, orientation, s);
                var basisPriority = k_DefaultAxisPriority;
                var sheared       = localToWorld.HasShear();

                if (localToWorld.HasNonUniformScale() || sheared)
                {
                    if (sheared)
                    {
                        basisPriority = GetBasisAxisPriority(basisToWorld);
                    }
                    MakeZAxisPrimaryBasis(ref basisPriority);
                }

                var bakeToShape =
                    GetPrimitiveBakeToShapeMatrix(localToWorld, shapeToWorld, ref center, ref orientation, 1f, basisPriority);

                height *= math.length(bakeToShape.c2);
                radius *= math.max(math.length(bakeToShape.c0), math.length(bakeToShape.c1));

                var axis = math.mul(orientation, new float3 {
                    z = 1f
                });
                var endPoint = axis * math.max(0f, 0.5f * height - radius);

                Capsule[0] = new CapsuleGeometry
                {
                    Vertex0 = center + endPoint,
                    Vertex1 = center - endPoint,
                    Radius  = radius
                };
                Center[0]      = center;
                Height[0]      = height;
                Orientation[0] = orientation;
            }
Beispiel #13
0
        public void PhysicsBodyCalculateAabb_CapsuleColliderTest()
        {
            var geometry = new CapsuleGeometry
            {
                Vertex0 = new float2(0f, -2f),
                Vertex1 = new float2(0f, 3f),
                Radius  = 1.5f
            };

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

            var physicsBody = new PhysicsBody(collider1);

            var aabb = physicsBody.CalculateAabb();

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

            collider1.Dispose();
            collider2.Dispose();
        }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        var ecb = new EntityCommandBuffer(Allocator.TempJob);

        //初始化角色控制器碰撞体(碰撞体为手动分配的内存,也需要手动释放)
        Entities
        .WithNone <CharacterControllerCollider>()
        .WithoutBurst()
        .ForEach((Entity e, MeshContainerComponent meshContainer, ref CharacterControllerInitializationData initData) => {
            //根据两点一半径构建胶囊几何体
            var capsule = new CapsuleGeometry {
                Vertex0 = initData.CapsuleCenter + new float3(0, 0.5f * initData.CapsuleHeight - initData.CapsuleRadius, 0),
                Vertex1 = initData.CapsuleCenter - new float3(0, 0.5f * initData.CapsuleHeight - initData.CapsuleRadius, 0),
                Radius  = initData.CapsuleRadius
            };
            //1为 1 << 0 第0层
            var filter = new CollisionFilter {
                BelongsTo = 1, CollidesWith = 1, GroupIndex = 0
            };
            var collider = Unity.Physics.CapsuleCollider.Create(capsule, filter, new Unity.Physics.Material {
                Flags = new Unity.Physics.Material.MaterialFlags()
            });
            //var collider = ColliderService.CreateCollider(meshContainer.Mesh, ColliderType.Capsule);
            ecb.AddComponent(e, new CharacterControllerCollider {
                Collider = collider
            });
        }).Run();    //使用Run来单线程运行?

        Entities
        .WithNone <CharacterControllerComponentData>()
        .ForEach((Entity e, ref CharacterControllerCollider collider) => {
            collider.Collider.Dispose();
            ecb.RemoveComponent <CharacterControllerCollider>(e);
        }).Run();

        ecb.Playback(EntityManager);
        ecb.Dispose();

        return(inputDeps);
    }
Beispiel #15
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        var ecb = new EntityCommandBuffer(Allocator.TempJob);

        Entities
        .WithNone <CharacterControllerCollider>()
        .ForEach((Entity e, ref CharacterControllerInitializationData initData) =>
        {
            var capsule = new CapsuleGeometry
            {
                Vertex0 = initData.CapsuleCenter + new float3(0, 0.5f * initData.CapsuleHeight - initData.CapsuleRadius, 0),
                Vertex1 = initData.CapsuleCenter - new float3(0, 0.5f * initData.CapsuleHeight - initData.CapsuleRadius, 0),
                Radius  = initData.CapsuleRadius
            };
            var filter = new CollisionFilter {
                BelongsTo = 1, CollidesWith = 1, GroupIndex = 0
            };
            var collider = Unity.Physics.CapsuleCollider.Create(capsule, filter, new Unity.Physics.Material {
                Flags = new Unity.Physics.Material.MaterialFlags()
            });
            ecb.AddComponent(e, new CharacterControllerCollider {
                Collider = collider
            });
        }).Run();

        Entities
        .WithNone <CharacterControllerComponentData>()
        .ForEach((Entity e, ref CharacterControllerCollider collider) =>
        {
            collider.Collider.Dispose();
            ecb.RemoveComponent <CharacterControllerCollider>(e);
        }).Run();

        ecb.Playback(EntityManager);
        ecb.Dispose();

        return(inputDeps);
    }
Beispiel #16
0
        public void TestPhysicsCapsuleColliderCreate()
        {
            var geometry = new CapsuleGeometry
            {
                Vertex0 = new float2(0f, -2f),
                Vertex1 = new float2(0f, 3f),
                Radius  = 1.5f
            };

            using (var colliderBlob = PhysicsCapsuleCollider.Create(geometry))
            {
                var collider = colliderBlob.GetColliderRef <PhysicsCapsuleCollider>();

                Assert.AreEqual(ColliderType.Capsule, collider.ColliderType);
                Assert.AreEqual(CollisionType.Convex, collider.CollisionType);

                Assert.AreEqual(geometry.Vertex0, collider.Vertex0);
                Assert.AreEqual(geometry.Vertex0, collider.Geometry.Vertex0);
                Assert.AreEqual(geometry.Vertex1, collider.Vertex1);
                Assert.AreEqual(geometry.Vertex1, collider.Geometry.Vertex1);
                Assert.AreEqual(geometry.Radius, collider.Radius);
                Assert.AreEqual(geometry.Radius, collider.Geometry.Radius);
            }
        }
Beispiel #17
0
 internal static float3 GetCenter(this CapsuleGeometry geometry) =>
 math.lerp(geometry.Vertex0, geometry.Vertex1, 0.5f);
Beispiel #18
0
        public void TestPhysicsCapsuleColliderCreateInvalid()
        {
            var geometry = new CapsuleGeometry
            {
                Vertex0 = new float2(0f, -2f),
                Vertex1 = new float2(0f, 3f),
                Radius  = 1.5f
            };

            // Invalid vertex0, positive infinity
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex0 = new float2(float.PositiveInfinity);
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }

            // Invalid vertex0, negative infinity
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex0 = new float2(float.NegativeInfinity);
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }

            // Invalid vertex0, nan
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex0 = new float2(float.NaN);
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }

            // Invalid vertex1, positive infinity
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex1 = new float2(float.PositiveInfinity);
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }

            // Invalid vertex1, negative infinity
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex1 = new float2(float.NegativeInfinity);
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }

            // Invalid vertex1, nan
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex1 = new float2(float.NaN);
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }

            // Negative radius
            {
                var invalidGeometry = geometry;
                invalidGeometry.Radius = -1.0f;
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }

            // Invalid radius, positive inf
            {
                var invalidGeometry = geometry;
                invalidGeometry.Radius = float.PositiveInfinity;
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }

            // Invalid radius, negative inf
            {
                var invalidGeometry = geometry;
                invalidGeometry.Radius = float.NegativeInfinity;
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }

            // Invalid radius, nan
            {
                var invalidGeometry = geometry;
                invalidGeometry.Radius = float.NaN;
                Assert.Throws <ArgumentException>(() => PhysicsCapsuleCollider.Create(invalidGeometry));
            }
        }
Beispiel #19
0
        // TODO: Currently, this system is responsible for creating and setting PhysicsImplementation properties
        //   -issue: PhysicsImplementations can't be passed/delegated before this system is initialized, as the props are unset
        //   -motive: DynamicMovementController wants to be able to setup callbacks before any physics events happen
        public void AddCharacterController(MoverComponent component)
        {
            var config = component.Config;

            var radius = 0.175f;

            // TODO: reduce duplicated code
            if (component.Mode == MoverComponent.MovementMode.Freecam)
            {
                var posPose = Matrix4x4.CreateTranslation(component.Transform.TransformationMatrix.Translation);
                var rot     = Matrix4x4.CreateRotationY(MathF.PI / -2f);

                var body = this.physxPhysics.CreateRigidDynamic(rot * posPose);
                body.MassSpaceInertiaTensor = new Vector3(0, 0, 0);
                body.Mass           = 175f;
                body.UserData       = component;
                body.RigidBodyFlags = RigidBodyFlag.Kinematic;

                var capsuleDesc = new CapsuleGeometry(radius, config.Height / 2f - radius);

                var shape = RigidActorExt.CreateExclusiveShape(body, capsuleDesc, characterControlMat);
                // TODO: centralize filter data construction
                shape.SimulationFilterData = new FilterData((uint)(OpenH2FilterData.NoClip | OpenH2FilterData.PlayerCharacter), 0, 0, 0);

                shape.ContactOffset = 0.001f;
                shape.RestOffset    = 0.0009f;

                var bodyProxy = new RigidBodyProxy(body);
                component.PhysicsImplementation = bodyProxy;
                this.physxScene.AddActor(body);
            }
            if (component.Mode == MoverComponent.MovementMode.KinematicCharacterControl)
            {
                var desc = new CapsuleControllerDesc()
                {
                    Height         = config.Height - .02f - (2 * radius),
                    Position       = component.Transform.Position,
                    Radius         = radius,
                    MaxJumpHeight  = 1f,
                    UpDirection    = EngineGlobals.Up,
                    SlopeLimit     = MathF.Cos(0.872665f), // cos(50 degrees)
                    StepOffset     = 0.1f,
                    Material       = defaultMat,
                    ContactOffset  = 0.0001f,
                    ReportCallback = new CustomHitReport()
                };

                var controller = this.controllerManager.CreateController <CapsuleController>(desc);

                controller.Actor.UserData       = component;
                component.PhysicsImplementation = new KinematicCharacterControllerProxy(controller);

                this.ControllerMap.Add(component, controller);
            }
            else if (component.Mode == MoverComponent.MovementMode.DynamicCharacterControl)
            {
                var posPose = Matrix4x4.CreateTranslation(component.Transform.TransformationMatrix.Translation);
                var rot     = Matrix4x4.CreateRotationY(MathF.PI / -2f);

                var body = this.physxPhysics.CreateRigidDynamic(rot * posPose);
                body.MassSpaceInertiaTensor = new Vector3(0, 0, 0);
                body.Mass     = 175f;
                body.UserData = component;

                var capsuleDesc = new CapsuleGeometry(radius, config.Height / 2f - radius);

                var shape = RigidActorExt.CreateExclusiveShape(body, capsuleDesc, characterControlMat);
                // TODO: centralize filter data construction
                shape.SimulationFilterData = new FilterData((uint)OpenH2FilterData.PlayerCharacter, 0, 0, 0);

                shape.ContactOffset = 0.001f;
                shape.RestOffset    = 0.0009f;

                var bodyProxy = new RigidBodyProxy(body);
                component.PhysicsImplementation = bodyProxy;
                this.physxScene.AddActor(body);

                if (component.State is DynamicMovementController dynamicMover)
                {
                    var contactInfo = ContactCallbackData.Normal;
                    this.contactProvider.RegisterContactCallback(body, contactInfo, dynamicMover.ContactFound);
                }
            }
        }
        public void TestCapsuleColliderCreateInvalid()
        {
            var geometry = new CapsuleGeometry
            {
                Vertex0 = new float3(5.66f, -6.72f, 0.12f),
                Vertex1 = new float3(0.98f, 8.88f, 9.54f),
                Radius  = 0.65f
            };

            // v0, +inf
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex0 = new float3(float.PositiveInfinity, 0.0f, 0.0f);
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }

            // v0, -inf
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex0 = new float3(float.NegativeInfinity, 0.0f, 0.0f);
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }

            // v0, nan
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex0 = new float3(float.NaN, 0.0f, 0.0f);
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }

            // v1, +inf
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex1 = new float3(float.PositiveInfinity, 0.0f, 0.0f);
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }

            // v1, -inf
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex1 = new float3(float.NegativeInfinity, 0.0f, 0.0f);
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }

            // v1, nan
            {
                var invalidGeometry = geometry;
                invalidGeometry.Vertex1 = new float3(float.NaN, 0.0f, 0.0f);
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }

            // negative radius
            {
                var invalidGeometry = geometry;
                invalidGeometry.Radius = -0.54f;
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }

            // radius, +inf
            {
                var invalidGeometry = geometry;
                invalidGeometry.Radius = float.PositiveInfinity;
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }

            // radius, -inf
            {
                var invalidGeometry = geometry;
                invalidGeometry.Radius = float.NegativeInfinity;
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }

            // radius, nan
            {
                var invalidGeometry = geometry;
                invalidGeometry.Radius = float.NaN;
                TestUtils.ThrowsException <System.ArgumentException>(() => CapsuleCollider.Create(invalidGeometry));
            }
        }
Beispiel #21
0
        protected override void OnUpdate()
        {
            Entities.ForEach((UnityEngine.CapsuleCollider2D collider) =>
            {
                // Convert the collider if it's valid.
                if (ConversionUtilities.CanConvertCollider(collider))
                {
                    try
                    {
                        UnityEngine.Vector3 vertex0;
                        UnityEngine.Vector3 vertex1;
                        float radius;

                        var halfSize = new float2(collider.size) * 0.5f;

                        if (collider.direction == UnityEngine.CapsuleDirection2D.Vertical)
                        {
                            radius  = halfSize.x;
                            vertex0 = new UnityEngine.Vector3(0.0f, halfSize.y - radius, 0.0f);
                            vertex1 = new UnityEngine.Vector3(0.0f, -halfSize.y + radius, 0.0f);
                        }
                        else
                        {
                            radius  = halfSize.y;
                            vertex0 = new UnityEngine.Vector3(halfSize.x - radius, 0.0f, 0.0f);
                            vertex1 = new UnityEngine.Vector3(-halfSize.x + radius, 0.0f, 0.0f);
                        }

                        // Add offset to capsule.
                        var colliderOffset = (UnityEngine.Vector3)collider.offset;
                        vertex0           += colliderOffset;
                        vertex1           += colliderOffset;

                        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 geometry = new CapsuleGeometry
                        {
                            Vertex0 = new float3(localToWorld.MultiplyPoint(vertex0)).xy,
                            Vertex1 = new float3(localToWorld.MultiplyPoint(vertex1)).xy,
                            Radius  = math.max(PhysicsSettings.Constants.MinimumConvexRadius, math.cmax(lossyScale) * radius),
                        };

                        var colliderBlob = PhysicsCapsuleCollider.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);
                    }
                }
            });
        }
    /// <summary>
    /// Generates a collider using a PhysicsShapeAuthoring and PhysicsMaterialsExtensionComponent
    /// </summary>
    /// <param name="shape"></param>
    /// <param name="shapeExt"></param>
    /// <param name="offsetPosition"></param>
    /// <param name="offsetRotation"></param>
    /// <returns></returns>
    BlobAssetReference <Unity.Physics.Collider> GenerateCollider(PhysicsShapeAuthoring shape, PhysicsMaterialsExtensionComponent shapeExt, out float3 offsetPosition, out quaternion offsetRotation)
    {
        CollisionFilter filter = new CollisionFilter
        {
            CollidesWith = shape.CollidesWith.Value,
            BelongsTo    = shape.BelongsTo.Value,
            GroupIndex   = 0
        };

        Unity.Physics.Material material = new Unity.Physics.Material
        {
            CollisionResponse        = shape.CollisionResponse,
            CustomTags               = shape.CustomTags.Value,
            Friction                 = shape.Friction.Value,
            FrictionCombinePolicy    = shape.Friction.CombineMode,
            Restitution              = shape.Restitution.Value,
            RestitutionCombinePolicy = shape.Restitution.CombineMode,
            EnableMassFactors        = shapeExt != null ? shapeExt.EnableMassFactors : false,
            EnableSurfaceVelocity    = shapeExt != null ? shapeExt.EnableSurfaceVelocity : false
        };
        switch (shape.ShapeType)
        {
        case ShapeType.Box:
            var boxProperties = shape.GetBoxProperties();
            offsetPosition = boxProperties.Center;
            offsetRotation = boxProperties.Orientation;
            return(Unity.Physics.BoxCollider.Create(boxProperties, filter, material));

        case ShapeType.Capsule:
            var capsuleProperties = shape.GetCapsuleProperties();
            var capsuleGeometry   = new CapsuleGeometry
            {
                Radius  = capsuleProperties.Radius,
                Vertex0 = capsuleProperties.Center - capsuleProperties.Height / 2 - capsuleProperties.Radius,
                Vertex1 = capsuleProperties.Center + capsuleProperties.Height / 2 - capsuleProperties.Radius
            };
            offsetPosition = capsuleProperties.Center;
            offsetRotation = capsuleProperties.Orientation;
            return(Unity.Physics.CapsuleCollider.Create(capsuleGeometry, filter, material));

        case ShapeType.Cylinder:
            var cylinderProperties = shape.GetCylinderProperties();
            offsetPosition = cylinderProperties.Center;
            offsetRotation = cylinderProperties.Orientation;
            return(CylinderCollider.Create(cylinderProperties, filter, material));

        case ShapeType.Sphere:
            var sphereProperties = shape.GetSphereProperties(out var orientation);
            var SphereGeometry   = new SphereGeometry
            {
                Center = sphereProperties.Center,
                Radius = sphereProperties.Radius
            };
            offsetPosition = sphereProperties.Center;
            offsetRotation = quaternion.identity;
            return(Unity.Physics.SphereCollider.Create(SphereGeometry, filter, material));

        case ShapeType.ConvexHull:
            NativeList <float3> points = new NativeList <float3>(Allocator.Temp);
            shape.GetConvexHullProperties(points);
            var ConvexCollider = Unity.Physics.ConvexCollider.Create(points, shape.ConvexHullGenerationParameters, filter, material);
            //    points.Dispose();
            offsetPosition = float3.zero;
            offsetRotation = quaternion.identity;
            return(ConvexCollider);

        case ShapeType.Mesh:
            NativeList <float3> verts = new NativeList <float3>(Allocator.Temp);
            NativeList <int3>   tris  = new NativeList <int3>(Allocator.Temp);
            shape.GetMeshProperties(verts, tris);
            offsetPosition = float3.zero;
            offsetRotation = quaternion.identity;
            return(Unity.Physics.MeshCollider.Create(verts, tris, filter, material));

        default:
            UnityEngine.Debug.LogWarning("GenerateCollider:: cannot generate collider for shapetype \"" + shape.ShapeType + "\"");
            offsetPosition = float3.zero;
            offsetRotation = quaternion.identity;
            return(new BlobAssetReference <Unity.Physics.Collider>());
        }
    }
Beispiel #23
0
 internal static float GetHeight(this CapsuleGeometry geometry) =>
 2f * geometry.Radius + math.length(geometry.Vertex1 - geometry.Vertex0);
    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
        });
    }
Beispiel #25
0
    BlobAssetReference <Unity.Physics.Collider> GenerateCollider(PhysicsShapeAuthoring shape, out float3 offsetPosition, out quaternion offsetRotation)
    {
        switch (shape.ShapeType)
        {
        case ShapeType.Box:
            var boxProperties = shape.GetBoxProperties();
            offsetPosition = boxProperties.Center;
            offsetRotation = boxProperties.Orientation;
            return(Unity.Physics.BoxCollider.Create(boxProperties));

        case ShapeType.Capsule:
            var capsuleProperties = shape.GetCapsuleProperties();
            var capsuleGeometry   = new CapsuleGeometry
            {
                Radius  = capsuleProperties.Radius,
                Vertex0 = capsuleProperties.Center - capsuleProperties.Height / 2 - capsuleProperties.Radius,
                Vertex1 = capsuleProperties.Center + capsuleProperties.Height / 2 - capsuleProperties.Radius
            };
            offsetPosition = capsuleProperties.Center;
            offsetRotation = capsuleProperties.Orientation;
            return(Unity.Physics.CapsuleCollider.Create(capsuleGeometry));

        case ShapeType.Cylinder:
            var cylinderProperties = shape.GetCylinderProperties();
            offsetPosition = cylinderProperties.Center;
            offsetRotation = cylinderProperties.Orientation;
            return(CylinderCollider.Create(cylinderProperties));

        case ShapeType.Sphere:
            var sphereProperties = shape.GetSphereProperties(out var orientation);
            var SphereGeometry   = new SphereGeometry
            {
                Center = sphereProperties.Center,
                Radius = sphereProperties.Radius
            };
            offsetPosition = sphereProperties.Center;
            offsetRotation = quaternion.identity;
            return(Unity.Physics.SphereCollider.Create(SphereGeometry));

        case ShapeType.ConvexHull:
            NativeList <float3> points = new NativeList <float3>(Allocator.Temp);
            shape.GetConvexHullProperties(points);
            var ConvexCollider = Unity.Physics.ConvexCollider.Create(points, shape.ConvexHullGenerationParameters);
            //    points.Dispose();
            offsetPosition = float3.zero;
            offsetRotation = quaternion.identity;
            return(ConvexCollider);

        case ShapeType.Mesh:
            NativeList <float3> verts = new NativeList <float3>(Allocator.Temp);
            NativeList <int3>   tris  = new NativeList <int3>(Allocator.Temp);
            shape.GetMeshProperties(verts, tris);
            offsetPosition = float3.zero;
            offsetRotation = quaternion.identity;
            return(Unity.Physics.MeshCollider.Create(verts, tris));

        default:
            UnityEngine.Debug.LogWarning("GenerateCollider:: cannot generate collider for shapetype \"" + shape.ShapeType + "\"");
            offsetPosition = float3.zero;
            offsetRotation = quaternion.identity;
            return(new BlobAssetReference <Unity.Physics.Collider>());
        }
    }