Shoot simulation problems

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
ChaosDev
Posts: 6
Joined: Fri Nov 05, 2010 7:39 am

Shoot simulation problems

Post by ChaosDev »

Hi. Im new in bepu and I have problems. I create a scene with static floor and few cubes. And im trying apply shoot on cubes using RayCast like this

Code: Select all

 List<Vector3> hitLocations = Resources.GetVectorList(), 
                    hitNormals = Resources.GetVectorList();
                List<float> hitTimes = Resources.GetFloatList();
                List<Entity> hitEntities = Resources.GetEntityList();

                Vector3 origin = Camera.Position;
                Vector3 direction = Camera.WorldMatrix.Forward; // WorldMatrix = Matrix.CreateFromAxisAngle(Vector3.Right, Pitch) * Matrix.CreateFromAxisAngle(Vector3.Up, Yaw);

                if (world.RayCast(origin,direction, 1000, true, hitEntities, hitLocations, hitNormals, hitTimes))
                {
                    float earliestTime = float.PositiveInfinity;
                    int earliestHitIndex = 0;
                    for (int k = 0; k < hitTimes.Count; k++)
                    {
                        if (hitEntities[k] != null && hitEntities[k].CollisionRules.Personal > CollisionRule.Normal)
                        {
                            //Don't bother selecting intangible/detector objects.
                            hitTimes[k] = float.PositiveInfinity;
                        }
                        else if (hitTimes[k] < earliestTime)
                        {
                            earliestTime = hitTimes[k];
                            earliestHitIndex = k;
                        }
                    }
                    //valid ray hit
                    if (hitEntities[earliestHitIndex] != null && hitTimes[earliestHitIndex] != float.PositiveInfinity && hitEntities[earliestHitIndex].IsDynamic)
                    {
                        //Apply the force.
                        Entity body = hitEntities[earliestHitIndex];
                        float force = 8.0f;
                        body.ApplyImpulse(hitLocations[earliestHitIndex], Vector3.Normalize(Camera.WorldMatrix.Forward)*force);
                    }
                }
And here is a questions.

1) Its a correct algorithm to apply impulse on point of object, like weapon shoot?
2) Collision raycast seem incorrect. Only when I displace cursor more to object center it start hit object ! For example

Not hit
Image

Hit
Image

bounding volume seem correct but why RayCast dont hit a physic object ? (also im trying change collision margin but its not help me).
Sorry if my english is bad. :(
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Shoot simulation problems

Post by Norbo »

It looks like the raycast should be working. That's very similar to the normal demos approach.

-Is your camera surrounded by any entity, like a sphere that follows it? That might cause unexpected results.
-What are the dimensions of the boxes involved? Extremely large dimensions could cause problems for the raycaster.
-Do you observe any similar behavior in the BEPUphysicsDemos when trying to 'grab' cubes with right click? Try creating a similar simulation in a demo and see if the grabber works as expected.
ChaosDev
Posts: 6
Joined: Fri Nov 05, 2010 7:39 am

Re: Shoot simulation problems

Post by ChaosDev »

-What are the dimensions of the boxes involved? Extremely large dimensions could cause problems for the raycaster.
Its just have size Vector3(1, 1, 1) Physic and drawing is correct proceed with this code, only the raycasting have trouble.

-What about first question -(What is a correct algorithm to apply impulse on point of object, like weapon shoot?) Can you answer me pls ? Nobody can answer this simple question however I asking on many forums. :(
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Shoot simulation problems

Post by Norbo »

Its just have size Vector3(1, 1, 1) Physic and drawing is correct proceed with this code, only the raycasting have trouble.
Raycasting should work fine for that size- that type of raycasting is done all the time in the demos though without issue. How often does it seem to happen? If you have a simple reproducible case, I could use the setup code/sample ray test to get more information.
What about first question -(What is a correct algorithm to apply impulse on point of object, like weapon shoot?)
Sorry about that, forgot about it in between reading it and pressing reply :)

It's a plenty good approximation. It will push it around depending on how you hit it, which is generally all players look for. The only issue you might observe is the when you're firing a very shallow angle. You might expect the bullet to ricochet off the surface, imparting very little force along the normal direction and maybe a little along the tangent direction in the form of friction.

If you wanted to simulate that kind of behavior, you could use the normal gotten from the raycast and the tangent computed from that normal and the ray direction.

Dot the ray direction with the normal and multiply by the force to get the normal force magnitude to apply. Apply an impulse of the normal multiplied by that magnitude.

Similarly compute the tangent force. You can simulate friction by limiting that tangent force according to some coefficient of friction multiplied by the normal force magnitude.

That isn't necessarily a 'realistic' model of how bullets impart force on walls. It treats them like a momentary rigid collision. In reality, it might get lodged in the material and the original approximation would have been closer (and simpler).
ChaosDev
Posts: 6
Joined: Fri Nov 05, 2010 7:39 am

Re: Shoot simulation problems

Post by ChaosDev »

Raycasting should work fine for that size- that type of raycasting is done all the time in the demos though without issue. How often does it seem to happen? If you have a simple reproducible case, I could use the setup code/sample ray test to get more information.
Well I send you my code. Hmm.. attaching..
That isn't necessarily a 'realistic' model of how bullets impart force on walls.
I dont want very realistically. Thank you for info but I think Im cannot do it without code sample.. And why it use hit normal without hit location ? Can you write a code sample here ? I not found anything about it in the internet.. :(
Attachments
Test.zip
This is a problem code...
(12.73 KiB) Downloaded 289 times
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Shoot simulation problems

Post by Norbo »

Well I send you my code. Hmm.. attaching..
It turns out there's a bug in the space's raycast that queries the broadPhase without margins regardless of what you put into the method for the withMargin parameter.

You can work around this by using the Space.BroadPhase's RayCast method directly. It's the same method that the Space uses internally, but for whatever reason the Space decided it was a good idea to always pass false in for the broadphase raycast withMargin parameter :)

By the way, I don't recommend using DiscreteGJK. It's mainly there for comparing, not usage. The default is a much better solution (DiscreteMPRGJK). DiscreteGJK and DiscreteMPR will be disappearing in v0.15.0.

I dont want very realistically. Thank you for info but I think Im cannot do it without code sample.. And why it use hit normal without hit location ? Can you write a code sample here ? I not found anything about it in the internet..
The hit location is used; I just left out some of the common parts in the explanation.

Your current model and the one I described are both unrealistic. If you already have one coded, I'd just use that one unless you don't like the behavior. If you do want a different behavior, figure out what that behavior is first before trying to code it. The problem is pretty much all about deciding on the behavior that you want- translating that into code is pretty easy.

I don't want to throw a chunk of code at you because I don't think it will really help that much. It might not be closer to what you actually want, and it will just be a mess of inscrutable code until you understand the concepts that would let you make it yourself. The necessary concepts are some of the fairly basic ones of working in 3d. Define your goal behavior clearly, translate that into geometrical/math terms, and translate that into code.
ChaosDev
Posts: 6
Joined: Fri Nov 05, 2010 7:39 am

Re: Shoot simulation problems

Post by ChaosDev »

It turns out there's a bug in the space's raycast that queries the broadPhase without margins regardless of what you put into the method for the withMargin parameter.

You can work around this by using the Space.BroadPhase's RayCast method directly. It's the same method that the Space uses internally, but for whatever reason the Space decided it was a good idea to always pass false in for the broadphase raycast withMargin parameter
Well I set margin to 0.0, replace raycasts to "scene.BroadPhase.RayCast(origin, direction, 1000, false, hitEntities, hitLocations, hitNormals, hitTimes)" and get same result :(
By the way, I don't recommend using DiscreteGJK. It's mainly there for comparing, not usage. The default is a much better solution (DiscreteMPRGJK). DiscreteGJK and DiscreteMPR will be disappearing in v0.15.0.
Thank for info, however I dont understand a difference between this modes.
The hit location is used; I just left out some of the common parts in the explanation.
"Perfectly" :roll: And I must invent these parts from void ?
I don't want to throw a chunk of code at you because I don't think it will really help that much. It might not be closer to what you actually want, and it will just be a mess of inscrutable code until you understand the concepts that would let you make it yourself. The necessary concepts are some of the fairly basic ones of working in 3d. Define your goal behavior clearly, translate that into geometrical/math terms, and translate that into code.
I just want basic code of correct momentary impulse applying from camera to dynamic object like box (without friction, ricochet etc). In the beginning the question itself was about this code -
body.ApplyImpulse(hitLocations[earliestHitIndex], Vector3.Normalize(Camera.WorldMatrix.Forward)*force); is correct or not for this task ? Im not so professional in math and physic like you, and in this situation I only can do conjectures. Even through you dont want explain code - explanation without common parts is obscure.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Shoot simulation problems

Post by Norbo »

Well I set margin to 0.0, replace raycasts to "scene.BroadPhase.RayCast(origin, direction, 1000, false, hitEntities, hitLocations, hitNormals, hitTimes)" and get same result
With default CollisionMargins and just switching out Broadphase for the Space, like so:

Code: Select all

scene.BroadPhase.RayCast(origin, direction, 1000, true, hitEntities, hitLocations, hitNormals, hitTimes)
You should see the rayhit obey the margin. The fact that it was being passed false by the space.RayCast regardless of what is passed in is the bug.

I don't recommend changing the collision margins of entities. See here for what it means and why it's used:
http://www.bepu-games.com/forums/viewto ... ?f=4&t=409
Thank for info, however I dont understand a difference between this modes.
They are different general case collision algorithms. When there isn't a special case collision algorithm available between a pair of entities, it falls back to the selected type of collision. In addition, choosing one of the continuous options enables continuous collision detection which prevents objects from flying through each other at a small performance cost.

DiscreteGJK and DiscreteMPR each use a certain part of the algorithms used by DiscreteMPRGJK. DiscreteMPRGJK's usage produces superior stability and speed.
"Perfectly" And I must invent these parts from void ?
For bullet impacts, the hit location is going to be the place where you apply whatever forces you compute, the same as your current method.
I just want basic code of correct momentary impulse applying from camera to dynamic object like box (without friction, ricochet etc).
The one you have now seems pretty good to me! It's a plenty plausible simulation of how a bullet might push a box. The alternative approach I described earlier is not a necessarily 'better' behavior, it's a different behavior. There's no point switching to some other approach if you're happy with the current one.

If there is a specific part of the behavior that you don't like, try to specifically state the goals of your ideal behavior. The first step doesn't need any math or code, just the statement of goals. If you can't identify anything wrong with it, then it's probably a perfectly fine approach :)
ChaosDev
Posts: 6
Joined: Fri Nov 05, 2010 7:39 am

Re: Shoot simulation problems

Post by ChaosDev »

Norbo wrote:With default CollisionMargins and just switching out Broadphase for the Space, like so:Code: Select allscene.BroadPhase.RayCast(origin, direction, 1000, true, hitEntities, hitLocations, hitNormals, hitTimes)You should see the rayhit obey the margin. The fact that it was being passed false by the space.RayCast regardless of what is passed in is the bug.
Sorry, but this has not affect on result. In this case im not set margin and it setted by default as 0.04 and collision continue avoid offset from border.
The some result receive when I squeeze a drawing box like this

Code: Select all

void initializeShape(Vector3 size)
        {

            Vector3 min = size;
            Vector3 max = size;
            
            
            min.X -= Body.CollisionMargin;
            min.Y -= Body.CollisionMargin;
            min.Z -= Body.CollisionMargin;

            max.X -= Body.CollisionMargin;
            max.Y -= Body.CollisionMargin;
            max.Z -= Body.CollisionMargin;
            

            BoundingBox boundingBox = new BoundingBox(-min/2, max/2);
            ....
}
Its reduce offset but if camera is close to object it happens again !
The one you have now seems pretty good to me! It's a plenty plausible simulation of how a bullet might push a box.
Phew :) Thats what exactly what I need in this case - a opinion of professional.

And finally, I have few opinions about thats stuff...

Why I not have same problem(about raycasting) when I use another NET physic engines - PhysX, BulletX, Matali ?
Why RayCast method result is so ugly ?
In PhysX for example -

Code: Select all

 RaycastHit hit = scene.RaycastClosestShape(CalcRay(Camera.MousePosition.X,
              Camera.MousePosition.Y, Camera), ShapesType.Dynamic);
So hit will contain all important information of necessary collision...
Clearly and exellent code... I think you must rewrite a RayCast to simular like this.
Phew.. dont be offended please :D
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Shoot simulation problems

Post by Norbo »

I've attached a modified version of your code. It appears to work fine other than the expected, extremely small rounded corner 'misses.'

The differences between what you originally posted and this code is the switch to use broadphase raycasts, and additionally, the boxes are drawn using the actual box data rather than boundingbox data. The BoundingBox is not guaranteed to be perfectly tight under all circumstances. In this case, the Box's bounding box was slightly expanded due to a special case.

To understand why the collision shape may not match your graphics exactly even if you use a perfect box, see the collision margins description I linked earlier:
http://www.bepu-games.com/forums/viewto ... ?f=4&t=409

The margin allows particularly speedy and powerful algorithms to be used in collision detection. Since it's a spherical expansion, a box becomes a slightly rounded box in the eyes of the algorithm. That's why corner shots can miss- there's no box there to hit.

v0.15.0 and v0.16.0 are adding more special cases to different parts of the engine. The Box shape is probably going to include the margin in its dimensions and raycasts against it will use the box special case currently used for marginless box raycasts for margin-expanded boxes. The slight 'rounded' edge effect will still happen when it is colliding with objects which do not have special cases with the Box, since the fallback algorithm is being used.
Why RayCast method result is so ugly ?
Note that you're using the multi-hit version of the method. There's a single hit version too, but the multi-hit version is there to support arbitrary filtering. All that extra looping and analysis of hit times and entities is filtering that isn't strictly necessary for what you're doing, it's for the demos.

The method signature itself is indeed a bit ugly. The raycasting system in general is getting a rewrite in v0.15.0, along with many other parts of the engine.
Attachments
PhysicsTest.zip
(306.62 KiB) Downloaded 324 times
ChaosDev
Posts: 6
Joined: Fri Nov 05, 2010 7:39 am

Re: Shoot simulation problems

Post by ChaosDev »

Finally with your code I get desired result. But only when I write this string after scene initialization...

Code: Select all

scene.SimulationSettings.CollisionDetection.DefaultMargin = 0.0f;
Phew. Thank you very much for interesting information and help.

And.. when 1.15 and 1.16 launch ?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Shoot simulation problems

Post by Norbo »

I would recommend not setting the default margin to 0; that will negatively impact performance and robustness of any entities created afterwards, unless you set the margins individually.

v0.15.0 shouldn't be extremely far away, but it's still too far to give a specific date. I can say that my goal is to have v0.15.0 and v0.16.0 out before the end of the year, and v0.15.0 has to come out before v0.16.0 ;)
Post Reply