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}" ); }
// 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]); } }
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) }); }
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 }; }
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); }
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); } }
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); } }
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; }
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); }
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); }
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); } }
internal static float3 GetCenter(this CapsuleGeometry geometry) => math.lerp(geometry.Vertex0, geometry.Vertex1, 0.5f);
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)); } }
// 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)); } }
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>()); } }
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 }); }
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>()); } }