As the topic states i have a compoundbody that is hit by a RayCast and it returns the CompundShape but not the ShapeEntry that was hit.
I use the current development version because in another thread there was hint that the CompoundBodys are better implemented there.
Getting CompoundBodys ShapeEntry hit by Raycast
Re: Getting CompoundBodys ShapeEntry hit by Raycast
CompoundChild contains an Entry property. While the default RayCast only returns the ray hit (normal, t, location) to match the BroadPhaseEntry requirements, the world space hierarchy can be queried directly for the CompoundChildren. You can look at the CompoundCollidable's RayCast method for an example of querying the hierarchy to find a collision.
I'll include a special ray cast for compounds which returns a RayCastResult or CompoundChild in the next development version. It would look something like this:
I'll include a special ray cast for compounds which returns a RayCastResult or CompoundChild in the next development version. It would look something like this:
Code: Select all
/// <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;
}
Re: Getting CompoundBodys ShapeEntry hit by Raycast
After some experimentation with youre code, i now get why its so complex to get that info.
I will make due with the CompundBody till the next DevVersion is out, thx.
I will make due with the CompundBody till the next DevVersion is out, thx.
Re: Getting CompoundBodys ShapeEntry hit by Raycast
I couldnt resist trying, so i wrote this extension class
now i got the CompoundChild i hit inside the Compound but its a CollisionShape and has no Tag and the shapeIndex is private, so i cant figure out what i hit.
Code: Select all
public static class CompoundBodyExtension{
public static bool InternalRayCast( this CompoundCollidable cb, Ray ray, float maximumLength, out RayHit rayHit, out CompoundChild hitChild ) {
rayHit = new RayHit();
hitChild = null;
var hitElements = new List<CompoundChild>();
if(cb.Hierarchy.Tree.GetOverlaps( ray, maximumLength, hitElements )) {
rayHit.T = float.MaxValue;
for(int i = 0 ; i < hitElements.Count ; i++) {
EntityCollidable candidate = hitElements[i].CollisionInformation;
RayHit tempHit;
if(candidate.RayCast( ray, maximumLength, out tempHit ) && tempHit.T < rayHit.T) {
rayHit = tempHit;
hitChild = hitElements[i];
}
}
return rayHit.T != float.MaxValue;
}
return false;
}
}
Re: Getting CompoundBodys ShapeEntry hit by Raycast
A CompoundChild contains an CollisionInformation property (returns an EntityCollidable, has a Tag) as well as an Entry property (uses the shape index to return the CompoundShapeEntry). The Entry property refers to the local space shape, its transform, and its weight (all retrieved from the CompoundShape used by the CompoundCollidable) but it doesn't have any Tag.
Re: Getting CompoundBodys ShapeEntry hit by Raycast
I construct my CompoundBody from CompoundShapeEntry's and they are constructed with a BoxShape, so can Tag only my CompoundBody.
Ok i'm a bit code blind, i just had to do CompoundBody.Children.indexOf(hitChild) to get the index, ok i can work with that, but it would be nice to Tag Shapes in the future.
thx.
Ok i'm a bit code blind, i just had to do CompoundBody.Children.indexOf(hitChild) to get the index, ok i can work with that, but it would be nice to Tag Shapes in the future.
thx.
Last edited by JanWH on Tue Jun 21, 2011 8:01 pm, edited 1 time in total.
Re: Getting CompoundBodys ShapeEntry hit by Raycast
If you're just trying to figure out if you hit a particular child shape, then testing equality between the desired shape instance and the entry's shape instance would do it. If that's not the goal, then I'm not understanding something.
Re: Getting CompoundBodys ShapeEntry hit by Raycast
While I probably won't add a Tag to CollisionShape itself, I am thinking about easier tagging for CompoundChildren, in the same way that a CompoundChild can have its material/event/collision rules initialized.it would be nice to Tag Shapes in the future.