public static unsafe BlobAssetReference <Collider> CreateTriangle(float3 vertex0, float3 vertex1, float3 vertex2, CollisionFilter filter, Material material) { SafetyChecks.CheckFiniteAndThrow(vertex0, nameof(vertex0)); SafetyChecks.CheckFiniteAndThrow(vertex1, nameof(vertex1)); SafetyChecks.CheckFiniteAndThrow(vertex2, nameof(vertex2)); var collider = new PolygonCollider(); collider.InitAsTriangle(vertex0, vertex1, vertex2, filter, material); return(BlobAssetReference <Collider> .Create(&collider, UnsafeUtility.SizeOf <PolygonCollider>())); }
public static BlobAssetReference <Collider> CreateTriangle(float3 vertex0, float3 vertex1, float3 vertex2, CollisionFilter?filter = null, Material?material = null) { if (math.any(!math.isfinite(vertex0)) || math.any(!math.isfinite(vertex1)) || math.any(!math.isfinite(vertex2))) { throw new System.ArgumentException("Tried to create triangle collider with nan/inf vertex"); } using (var allocator = new BlobAllocator(-1)) { ref PolygonCollider collider = ref allocator.ConstructRoot <PolygonCollider>(); collider.InitAsTriangle(vertex0, vertex1, vertex2, filter ?? CollisionFilter.Default, material ?? Material.Default); return(allocator.CreateBlobAssetReference <Collider>(Allocator.Persistent)); }
public static unsafe BlobAssetReference <Collider> CreateQuad(float3 vertex0, float3 vertex1, float3 vertex2, float3 vertex3, CollisionFilter filter, Material material) { SafetyChecks.CheckFiniteAndThrow(vertex0, nameof(vertex0)); SafetyChecks.CheckFiniteAndThrow(vertex1, nameof(vertex1)); SafetyChecks.CheckFiniteAndThrow(vertex2, nameof(vertex2)); SafetyChecks.CheckFiniteAndThrow(vertex3, nameof(vertex3)); SafetyChecks.CheckCoplanarAndThrow(vertex0, vertex1, vertex2, vertex3, nameof(vertex3)); PolygonCollider collider = default; collider.InitAsQuad(vertex0, vertex1, vertex2, vertex3, filter, material); return(BlobAssetReference <Collider> .Create(&collider, UnsafeUtility.SizeOf <PolygonCollider>())); }
public static unsafe BlobAssetReference <Collider> CreateTriangle(float3 vertex0, float3 vertex1, float3 vertex2, CollisionFilter filter, Material material) { if (math.any(!math.isfinite(vertex0)) || math.any(!math.isfinite(vertex1)) || math.any(!math.isfinite(vertex2))) { throw new ArgumentException("Tried to create triangle collider with nan/inf vertex"); } var collider = new PolygonCollider(); collider.InitAsTriangle(vertex0, vertex1, vertex2, filter, material); return(BlobAssetReference <Collider> .Create(&collider, UnsafeUtility.SizeOf <PolygonCollider>())); }
public static unsafe BlobAssetReference <Collider> CreateQuad(float3 vertex0, float3 vertex1, float3 vertex2, float3 vertex3, CollisionFilter filter, Material material) { if (math.any(!math.isfinite(vertex0)) || math.any(!math.isfinite(vertex1)) || math.any(!math.isfinite(vertex2)) || math.any(!math.isfinite(vertex3))) { throw new ArgumentException("Tried to create triangle collider with nan/inf vertex"); } // check if vertices are co-planar float3 normal = math.normalize(math.cross(vertex1 - vertex0, vertex2 - vertex0)); if (math.abs(math.dot(normal, vertex3 - vertex0)) > 1e-3f) { throw new ArgumentException("Vertices for quad creation are not co-planar"); } PolygonCollider collider = default; collider.InitAsQuad(vertex0, vertex1, vertex2, vertex3, filter, material); return(BlobAssetReference <Collider> .Create(&collider, UnsafeUtility.SizeOf <PolygonCollider>())); }
public void AddColliderKeys(ColliderKey *keys, int count) { var colliderKeys = new ColliderKeyPair { ColliderKeyA = m_ConvexColliderKey, ColliderKeyB = m_ConvexColliderKey }; CollisionFilter filter = m_ConvexColliderA->Filter; // Collide the convex A with all overlapping leaves of B switch (m_CompositeColliderB->Type) { // Special case meshes (since we know all polygons will be built on the fly) case ColliderType.Mesh: { Mesh *mesh = &((MeshCollider *)m_CompositeColliderB)->Mesh; uint numMeshKeyBits = mesh->NumColliderKeyBits; var polygon = new PolygonCollider(); polygon.InitEmpty(); for (int i = 0; i < count; i++) { ColliderKey compositeKey = m_CompositeColliderKeyPath.GetLeafKey(keys[i]); uint meshKey = compositeKey.Value >> (32 - (int)numMeshKeyBits); if (mesh->GetPolygon(meshKey, filter, ref polygon)) { if (m_Flipped) { colliderKeys.ColliderKeyA = compositeKey; } else { colliderKeys.ColliderKeyB = compositeKey; } switch (m_ConvexColliderA->CollisionType) { case CollisionType.Convex: ConvexConvex( m_Context, colliderKeys, m_ConvexColliderA, (Collider *)&polygon, m_WorldFromA, m_WorldFromB, m_CollisionTolerance, m_Flipped); break; case CollisionType.Terrain: TerrainConvex( m_Context, colliderKeys, m_ConvexColliderA, (Collider *)&polygon, m_WorldFromA, m_WorldFromB, m_CollisionTolerance, m_Flipped); break; default: // GetLeaf() may not return a composite collider throw new NotImplementedException(); } } } } break; // General case for all other composites (compounds, compounds of meshes, etc) default: { for (int i = 0; i < count; i++) { ColliderKey compositeKey = m_CompositeColliderKeyPath.GetLeafKey(keys[i]); m_CompositeColliderB->GetLeaf(compositeKey, out ChildCollider leaf); if (CollisionFilter.IsCollisionEnabled(filter, leaf.Collider->Filter)) // TODO: shouldn't be needed if/when filtering is done fully by the BVH query { if (m_Flipped) { colliderKeys.ColliderKeyA = compositeKey; } else { colliderKeys.ColliderKeyB = compositeKey; } MTransform worldFromLeafB = Mul(m_WorldFromB, new MTransform(leaf.TransformFromChild)); switch (leaf.Collider->CollisionType) { case CollisionType.Convex: ConvexConvex( m_Context, colliderKeys, m_ConvexColliderA, leaf.Collider, m_WorldFromA, worldFromLeafB, m_CollisionTolerance, m_Flipped); break; case CollisionType.Terrain: ConvexTerrain( m_Context, colliderKeys, m_ConvexColliderA, leaf.Collider, m_WorldFromA, worldFromLeafB, m_CollisionTolerance, m_Flipped); break; default: // GetLeaf() may not return a composite collider throw new NotImplementedException(); } } } } break; } }