/// <summary> /// Casts a convex shape against the collidable. /// </summary> /// <param name="castShape">Shape to cast.</param> /// <param name="startingTransform">Initial transform of the shape.</param> /// <param name="sweep">Sweep to apply to the shape.</param> /// <param name="filter">Test to apply to the entry. If it returns true, the entry is processed, otherwise the entry is ignored. If a collidable hierarchy is present /// in the entry, this filter will be passed into inner ray casts.</param> /// <param name="hit">Hit data, if any.</param> /// <param name="hitChild">Child hit by the cast.</param> /// <returns>Whether or not the cast hit anything.</returns> public bool ConvexCast(ConvexShape castShape, ref RigidTransform startingTransform, ref Vector3 sweep, Func <BroadPhaseEntry, bool> filter, out RayHit hit, out CompoundChild hitChild) { hit = new RayHit(); hitChild = null; if (!filter(this)) { return(false); } BoundingBox boundingBox; castShape.GetSweptBoundingBox(ref startingTransform, ref sweep, out boundingBox); var hitElements = PhysicsResources.GetCompoundChildList(); if (hierarchy.Tree.GetOverlaps(boundingBox, hitElements)) { hit.T = float.MaxValue; for (int i = 0; i < hitElements.Count; i++) { var candidate = hitElements.Elements[i].CollisionInformation; RayHit tempHit; if (candidate.ConvexCast(castShape, ref startingTransform, ref sweep, filter, out tempHit) && tempHit.T < hit.T) { hit = tempHit; hitChild = hitElements.Elements[i]; } } PhysicsResources.GiveBack(hitElements); return(hit.T != float.MaxValue); } PhysicsResources.GiveBack(hitElements); return(false); }
/// <summary> /// Tests a ray against the collidable. /// </summary> /// <param name="ray">Ray to test.</param> /// <param name="maximumLength">Maximum length, in units of the ray's direction's length, to test.</param> /// <param name="filter">Test to apply to the entry. If it returns true, the entry is processed, otherwise the entry is ignored. If a collidable hierarchy is present /// in the entry, this filter will be passed into inner ray casts.</param> /// <param name="rayHit">Hit location of the ray on the collidable, if any.</param> /// <param name="hitChild">Child hit by the ray.</param> /// <returns>Whether or not the ray hit the collidable.</returns> public bool RayCast(Ray ray, float maximumLength, Func <BroadPhaseEntry, bool> filter, out RayHit rayHit, out CompoundChild hitChild) { rayHit = new RayHit(); hitChild = null; if (filter(this)) { var hitElements = PhysicsResources.GetCompoundChildList(); if (hierarchy.Tree.GetOverlaps(ray, maximumLength, hitElements)) { rayHit.T = float.MaxValue; for (int i = 0; i < hitElements.Count; i++) { RayHit tempHit; if (hitElements.Elements[i].CollisionInformation.RayCast(ray, maximumLength, filter, out tempHit) && tempHit.T < rayHit.T) { rayHit = tempHit; hitChild = hitElements.Elements[i]; } } PhysicsResources.GiveBack(hitElements); return(rayHit.T != float.MaxValue); } PhysicsResources.GiveBack(hitElements); } return(false); }
/// <summary> /// Tests a ray against the collidable. /// </summary> /// <param name="ray">Ray to test.</param> /// <param name="maximumLength">Maximum length, in units of the ray's direction's length, to test.</param> /// <param name="rayHit">Hit data, if any.</param> /// <param name="hitChild">Child collidable hit by the ray, if any.</param> /// <returns>Whether or not the ray hit the entry.</returns> public bool RayCast(Ray ray, float maximumLength, out RayHit rayHit, out CompoundChild hitChild) { rayHit = new RayHit(); hitChild = null; var hitElements = PhysicsResources.GetCompoundChildList(); if (hierarchy.Tree.GetOverlaps(ray, maximumLength, hitElements)) { rayHit.T = float.MaxValue; for (int i = 0; i < hitElements.Count; i++) { EntityCollidable candidate = hitElements.Elements[i].CollisionInformation; RayHit tempHit; if (candidate.RayCast(ray, maximumLength, out tempHit) && tempHit.T < rayHit.T) { rayHit = tempHit; hitChild = hitElements.Elements[i]; } } PhysicsResources.GiveBack(hitElements); return(rayHit.T != float.MaxValue); } PhysicsResources.GiveBack(hitElements); return(false); }
protected override void UpdateContainedPairs() { var overlappedElements = PhysicsResources.GetCompoundChildList(); compoundInfo.hierarchy.Tree.GetOverlaps(convexInfo.boundingBox, overlappedElements); for (int i = 0; i < overlappedElements.Count; i++) { TryToAdd(overlappedElements.Elements[i].CollisionInformation, CollidableB, overlappedElements.Elements[i].Material); } PhysicsResources.GiveBack(overlappedElements); }
protected override void UpdateContainedPairs() { //Could go other way; get triangles in mesh that overlap the compound. //Could be faster sometimes depending on the way it's set up. var overlappedElements = PhysicsResources.GetCompoundChildList(); compoundInfo.hierarchy.Tree.GetOverlaps(terrain.boundingBox, overlappedElements); for (int i = 0; i < overlappedElements.Count; i++) { TryToAdd(overlappedElements.Elements[i].CollisionInformation, terrain, overlappedElements.Elements[i].Material, terrain.Material); } PhysicsResources.GiveBack(overlappedElements); }
protected override void UpdateContainedPairs() { //TODO: Static triangle meshes have a worldspace hierarchy that could be more efficiently traversed with a tree vs tree test. //This is just a lot simpler to manage in the short term. var overlappedElements = PhysicsResources.GetCompoundChildList(); compoundInfo.hierarchy.Tree.GetOverlaps(mesh.boundingBox, overlappedElements); for (int i = 0; i < overlappedElements.Count; i++) { TryToAdd(overlappedElements.Elements[i].CollisionInformation, mesh, overlappedElements.Elements[i].Material, mesh.material); } PhysicsResources.GiveBack(overlappedElements); }