static public BlobAssetReference <Collider> ProduceColliderBlob (this UnityEngine.CapsuleCollider shape, int groupIndex) { var linearScale = (float3)shape.transform.lossyScale; // radius is max of the two non-height axes var radius = shape.radius * math.cmax(new float3(math.abs(linearScale)) { [shape.direction] = 0f }); var ax = new float3 { [shape.direction] = 1f }; var vertex = ax * (0.5f * shape.height); var rt = new RigidTransform(shape.transform.rotation, shape.transform.position); var worldCenter = math.mul(shape.transform.localToWorldMatrix, new float4(shape.center, 0f)); var offset = math.mul(math.inverse(new float4x4(rt)), worldCenter).xyz - shape.center * math.abs(linearScale); var v0 = offset + ((float3)shape.center + vertex) * math.abs(linearScale) - ax * radius; var v1 = offset + ((float3)shape.center - vertex) * math.abs(linearScale) + ax * radius; return(CapsuleCollider.Create( new CapsuleGeometry { Vertex0 = v0, Vertex1 = v1, Radius = radius }, GetFilter(shape, groupIndex) //ProduceCollisionFilter( shape ), //ProduceMaterial( shape ) )); }
protected override void Start() { base.Start(); //base.init(float3.zero); // no gravity // Enable the joint viewer SetDebugDisplay(new Unity.Physics.Authoring.PhysicsDebugDisplayData { DrawJoints = 1, DrawContacts = 1 }); const uint layerBody = (1 << 0); const uint layerHead = (1 << 1); const uint layerUpperArm = (1 << 2); const uint layerForearm = (1 << 3); const uint layerHand = (1 << 4); const uint layerThigh = (1 << 5); // const uint layerCalf = (1 << 6); // const uint layerFoot = (1 << 7); const int layerGround = (1 << 8); // Floor { BlobAssetReference <Collider> collider = BoxCollider.Create(float3.zero, Quaternion.identity, new float3(20.0f, 0.2f, 20.0f), 0.01f, filter(layerGround, 0)); CreateStaticBody(new float3(0, -0.1f, 0), quaternion.identity, collider); } // Body float3 bodyHalfExtents = new float3(0.2f, 0.3f, 0.075f); float3 bodyPosition = new float3(0, 0.1f, 0); Entity body; { BlobAssetReference <Collider> collider = BoxCollider.Create( float3.zero, Quaternion.identity, 2.0f * bodyHalfExtents, 0.01f, filter(layerBody, layerHead | layerUpperArm | layerThigh)); quaternion q = quaternion.AxisAngle(new float3(1, 0, 0), (float)math.PI / 2.0f); body = CreateDynamicBody(bodyPosition, quaternion.identity, collider, float3.zero, float3.zero, 10.0f); //body = createStaticBody(bodyPosition, quaternion.identity, collider); } // Arms { float handLength = 0.025f; float handRadius = 0.055f; BlobAssetReference <Collider> handCollider = CapsuleCollider.Create(new float3(-handLength / 2, 0, 0), new float3(handLength / 2, 0, 0), handRadius, filter(layerHand, layerForearm)); for (int i = 0; i < 1; i++) { float s = i * 2 - 1.0f; float3 handPosition = new float3(0, 0.3f, 0); Entity hand = CreateDynamicBody(handPosition, quaternion.identity, handCollider, float3.zero, float3.zero, 10.0f); } } }
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) }); }
public static BlobAssetReference <Collider> CreateCollider(UnityEngine.Mesh mesh, ColliderType type) { switch (type) { case ColliderType.Sphere: { Bounds bounds = mesh.bounds; return(SphereCollider.Create(new SphereGeometry { Center = bounds.center, Radius = math.cmax(bounds.extents) })); } case ColliderType.Triangle: { return(PolygonCollider.CreateTriangle(mesh.vertices[0], mesh.vertices[1], mesh.vertices[2])); } case ColliderType.Quad: { // We assume the first 2 triangles of the mesh are a quad with a shared edge // Work out a correct ordering for the triangle int[] orderedIndices = new int[4]; // Find the vertex in first triangle that is not on the shared edge for (int i = 0; i < 3; i++) { if ((mesh.triangles[i] != mesh.triangles[3]) && (mesh.triangles[i] != mesh.triangles[4]) && (mesh.triangles[i] != mesh.triangles[5])) { // Push in order or prev, unique, next orderedIndices[0] = mesh.triangles[(i - 1 + 3) % 3]; orderedIndices[1] = mesh.triangles[i]; orderedIndices[2] = mesh.triangles[(i + 1) % 3]; break; } } // Find the vertex in second triangle that is not on a shared edge for (int i = 3; i < 6; i++) { if ((mesh.triangles[i] != orderedIndices[0]) && (mesh.triangles[i] != orderedIndices[1]) && (mesh.triangles[i] != orderedIndices[2])) { orderedIndices[3] = mesh.triangles[i]; break; } } return(PolygonCollider.CreateQuad( mesh.vertices[orderedIndices[0]], mesh.vertices[orderedIndices[1]], mesh.vertices[orderedIndices[2]], mesh.vertices[orderedIndices[3]])); } case ColliderType.Box: { Bounds bounds = mesh.bounds; return(BoxCollider.Create(new BoxGeometry { Center = bounds.center, Orientation = quaternion.identity, Size = 2.0f * bounds.extents, BevelRadius = 0.0f })); } case ColliderType.Capsule: { Bounds bounds = mesh.bounds; float min = math.cmin(bounds.extents); float max = math.cmax(bounds.extents); int x = math.select(math.select(2, 1, min == bounds.extents.y), 0, min == bounds.extents.x); int z = math.select(math.select(2, 1, max == bounds.extents.y), 0, max == bounds.extents.x); int y = math.select(math.select(2, 1, (1 != x) && (1 != z)), 0, (0 != x) && (0 != z)); float radius = bounds.extents[y]; float3 vertex0 = bounds.center; vertex0[z] = -(max - radius); float3 vertex1 = bounds.center; vertex1[z] = (max - radius); return(CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = vertex0, Vertex1 = vertex1, Radius = radius })); } case ColliderType.Cylinder: // TODO: need someone to add throw new NotImplementedException(); case ColliderType.Convex: { NativeArray <float3> points = new NativeArray <float3>(mesh.vertices.Length, Allocator.TempJob); for (int i = 0; i < mesh.vertices.Length; i++) { points[i] = mesh.vertices[i]; } BlobAssetReference <Collider> collider = ConvexCollider.Create(points, default, CollisionFilter.Default); points.Dispose(); return(collider); }
protected override void Start() { base.Start(); const uint layerBody = (1 << 0); const uint layerHead = (1 << 1); const uint layerUpperArm = (1 << 2); const uint layerForearm = (1 << 3); const uint layerHand = (1 << 4); const uint layerThigh = (1 << 5); // const uint layerCalf = (1 << 6); // const uint layerFoot = (1 << 7); const int layerGround = (1 << 8); // Floor { BlobAssetReference <Collider> collider = BoxCollider.Create(new BoxGeometry { Center = float3.zero, Orientation = quaternion.identity, Size = new float3(20.0f, 0.2f, 20.0f), BevelRadius = 0.01f }, filter(layerGround, 0), Material.Default); CreateStaticBody(new float3(0, -0.1f, 0), quaternion.identity, collider); } // Body float3 bodyHalfExtents = new float3(0.2f, 0.3f, 0.075f); float3 bodyPosition = new float3(0, 0.1f, 0); Entity body; { BlobAssetReference <Collider> collider = BoxCollider.Create(new BoxGeometry { Center = float3.zero, Orientation = quaternion.identity, Size = 2.0f * bodyHalfExtents, BevelRadius = 0.01f }, filter(layerBody, layerHead | layerUpperArm | layerThigh), Material.Default); quaternion q = quaternion.AxisAngle(new float3(1, 0, 0), (float)math.PI / 2.0f); body = CreateDynamicBody(bodyPosition, quaternion.identity, collider, float3.zero, float3.zero, 10.0f); //body = createStaticBody(bodyPosition, quaternion.identity, collider); } // Arms { float handLength = 0.025f; float handRadius = 0.055f; BlobAssetReference <Collider> handCollider = CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = new float3(-handLength / 2, 0, 0), Vertex1 = new float3(handLength / 2, 0, 0), Radius = handRadius }, filter(layerHand, layerForearm), Material.Default); for (int i = 0; i < 1; i++) { float s = i * 2 - 1.0f; float3 handPosition = new float3(0, 0.3f, 0); Entity hand = CreateDynamicBody(handPosition, quaternion.identity, handCollider, float3.zero, float3.zero, 10.0f); } } }