/// <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 = Resources.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]; } } Resources.GiveBack(hitElements); return(rayHit.T != float.MaxValue); } Resources.GiveBack(hitElements); return(false); }
///<summary> /// Constructs a new CompoundCollidable. ///</summary> ///<param name="compoundShape">Compound shape to use for the collidable.</param> public CompoundCollidable(CompoundShape compoundShape) : base(compoundShape) { for (int i = 0; i < compoundShape.shapes.count; i++) { CompoundChild child = GetChild(compoundShape.shapes.Elements[i], i); this.children.Add(child); } hierarchy = new CompoundHierarchy(this); }
///<summary> /// Constructs a new compound hierarchy. ///</summary> ///<param name="owner">Owner of the hierarchy.</param> public CompoundHierarchy(CompoundCollidable owner) { this.owner = owner; var children = new CompoundChild[owner.children.count]; Array.Copy(owner.children.Elements, children, owner.children.count); //In order to initialize a good tree, the local space bounding boxes should first be computed. //Otherwise, the tree would try to create a hierarchy based on a bunch of zeroed out bounding boxes! for (int i = 0; i < children.Length; i++) { children[i].CollisionInformation.worldTransform = owner.Shape.shapes.Elements[i].LocalTransform; children[i].CollisionInformation.UpdateBoundingBoxInternal(0); } tree = new BoundingBoxTree<CompoundChild>(children); }
///<summary> /// Constructs a new compound hierarchy. ///</summary> ///<param name="owner">Owner of the hierarchy.</param> public CompoundHierarchy(CompoundCollidable owner) { this.owner = owner; var children = new CompoundChild[owner.children.count]; Array.Copy(owner.children.Elements, children, owner.children.count); //In order to initialize a good tree, the local space bounding boxes should first be computed. //Otherwise, the tree would try to create a hierarchy based on a bunch of zeroed out bounding boxes! for (int i = 0; i < children.Length; i++) { children[i].CollisionInformation.worldTransform = owner.Shape.shapes.Elements[i].LocalTransform; children[i].CollisionInformation.UpdateBoundingBoxInternal(0); } tree = new BoundingBoxTree <CompoundChild>(children); }
/// <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 = Resources.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]; } } Resources.GiveBack(hitElements); return rayHit.T != float.MaxValue; } Resources.GiveBack(hitElements); return false; }