Getting CompoundBodys ShapeEntry hit by Raycast

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
JanWH
Posts: 11
Joined: Sat Nov 06, 2010 5:48 pm

Getting CompoundBodys ShapeEntry hit by Raycast

Post by JanWH »

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.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Getting CompoundBodys ShapeEntry hit by Raycast

Post by Norbo »

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:

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;
        }
JanWH
Posts: 11
Joined: Sat Nov 06, 2010 5:48 pm

Re: Getting CompoundBodys ShapeEntry hit by Raycast

Post by JanWH »

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.
JanWH
Posts: 11
Joined: Sat Nov 06, 2010 5:48 pm

Re: Getting CompoundBodys ShapeEntry hit by Raycast

Post by JanWH »

I couldnt resist trying, so i wrote this extension class

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;
		}
	}
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.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Getting CompoundBodys ShapeEntry hit by Raycast

Post by Norbo »

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.
JanWH
Posts: 11
Joined: Sat Nov 06, 2010 5:48 pm

Re: Getting CompoundBodys ShapeEntry hit by Raycast

Post by JanWH »

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.
Last edited by JanWH on Tue Jun 21, 2011 8:01 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Getting CompoundBodys ShapeEntry hit by Raycast

Post by Norbo »

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.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Getting CompoundBodys ShapeEntry hit by Raycast

Post by Norbo »

it would be nice to Tag Shapes in the future.
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.
Post Reply