Controlled Physics

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
goldsword
Posts: 18
Joined: Fri Dec 05, 2008 8:46 pm

Controlled Physics

Post by goldsword »

Hi, I'm experementing with a control scheme and player world interaction using BEPU and have ran into some problem, well not problems but I'd like to share and get ideas how one would go about this.

Visualise a terrain together with a small village, also put the camera in 3rd person. Now you want the player to control the character using the direction sticks on your controller. You also want the player to be able to walk on the terrain in a natural manner, some slopes are just to steep and should not be allowed to walk. In the village there are houses, they should simply collide with the player.

With this problem and only an hour with BEPU I decided to represent the player as a cylinder, giving a tight fit to the model, I also removed any rotation by assigning a zero intertia tensor, hooked up the rotation of the cylinder to the gamepad direction keys and started using move inorder to walk the character. The terrain was generated from a heightmap and put into the world using the Terrain object. Finally the house was created using a simple box.
This worked quite well, the gravity would automatically hinder the player from climbing the mountains but the house collision was behaving strange, it turned out move will not support collision detection. After some searching I found internalLinearVelocity and changed so the controller would instead change this manually. Nothing happened but after some trying I noticed that calling move(Vector3.Zero) after setting the velocity would result in correct behaviour, probably due to the object being in some kind of resting state until woken up (is there a method like .wakeUp?). Now the player would collide with the house but ofcourse I've ran into a bunch of other problems, by setting the velocity manually I destroyed gravity. Before trying to solve this I'd like to know if I'm on the right track or if theres a much better way of doing this.

Also, is there any difference in having the house as a box without mass (#1) over adding it to a StaticGroup instead (#2)?

// #1
box = new BEPUphysics.Box(new Vector3(10f, 0f, 10f), 1.5f, .5f, 10f);
physicalWorld.add(box);

// #2
BEPUphysics.StaticGroup houseGrp = new BEPUphysics.StaticGroup(5f, 1f, 1);
houseGrp.addEntity(box);
physicalWorld.add(houseGrp);

Basically, will I gain performance by adding my houses to a static group over adding them directly to the space object?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Controlled Physics

Post by Norbo »

You can use entity.activate(); to wake objects up. Alternatively, you can set the entity's isAlwaysActive flag to true so you don't need to worry about it later (characters don't really need to sleep). The entity.move and entity.moveTo will indeed cause collision issues since they act like teleports rather than a physical motion. Have you tried the demos CharacterController class? It should handle what you need. Getting a general purpose 'fps-like' character working in a 3D environment can be a bit of a chore otherwise.

As for the StaticGroup, I would recommend leaving your entities outside of it for simplicity's sake unless you start experiencing slowdowns from too many static entities (you'd need quite a lot of static objects to reach this point). The StaticTriangleGroup is another alternative for level geometry if you need a faster general geometry method.
goldsword
Posts: 18
Joined: Fri Dec 05, 2008 8:46 pm

Re: Controlled Physics

Post by goldsword »

I just tried the character controller class, it appears to do what I want! However I'm having a hard time constraining my character.
For instance I want to control how quickly he moves, but setting the capsules height will give different movement behaviour.
I also dont understand what the following variables will do:

1. maximumGlueSpeed (I'm using 0)
2. supportEntityForceApplicationFactor (I'm using 0)
3. maximumStepSlope (I'm using Pi/4)

Is there a way to make the capsules shape not effect the motion?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Controlled Physics

Post by Norbo »

maximumGlueSpeed will 'glue' the character to the ground if the ground is separating from the character with a speed less than maximumGlueSpeed. This helps the character stand on things that are moving up and down without constantly falling and jittering.

supportEntityForceApplicationFactor is the amount of force to use on things the character stands on. For example, when your character stands on the high end of a sea saw, the extra weight will pull down that end. A factor of 1 just means that the force physically required to keep the character standing is applied to the support. Usually, this value is lower than 1 (between 0 and 1) to lessen the forces. A factor of 0 means that objects do not have force exerted on them from the character walking on them. Though these values are not physically 'correct,' the character won't fall through anything. Other entities will still undergo regular collision response with the body of the character regardless of the factor.

maximumStepSlope can be used to prevent the character from stepping to or from a surface which is too steep, separately defined from the usual steepness limit, maximumSlope.


In what way are you setting the capsule's height, and how does it respond when you change it? The usual method is to define the total height (bodyHeight) of the character in the constructor since modifying the height of the capsule itself after initializiation can have side effects. Note that having a large body radius compared to height can cause issues as well since the capsule could be created with a negative height (see the characercontroller constructor).
goldsword
Posts: 18
Joined: Fri Dec 05, 2008 8:46 pm

Re: Controlled Physics

Post by goldsword »

Thanks for the support, I've fixed all my problems by going back to my original design, I didnt get the Character class to work properly. The character was more or less always regarded as airborne, just bumping into obsticles would make him airborne and once airborne the capsule would pickup greater and greater velocities even though max velocity was set, and the terrain would have big problems detecting collision with the player.
My alternative solution is to use normal physics but turn zero tensor to keep the player upright, using Impulse to move the player and capping the player (x,z) velocity each frame, works perfectly!

I have also tried out alot of different things with the engine and I must say I'm widely impressed and the engine interface is great. Currently however I'm having some problems. rayCast will sometimes miss my objects (quite random), I think I might be able to work around this by using a larger ray then needed? For instance right now I'm firing a gun, the projectile is basically 2 set of points, last frame and current frame (not integrated with BEPU in anyway), then each frame the projectile will move apply gravity etc and update the position, then a rayCast is made between last position and current position but sometimes terrain or objects residing between the positions will be missed.

Another issue I have is with CompundObjects, I cant seem to create a non dynamic one, when using children that are none dynamic I get a null ref exception.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Controlled Physics

Post by Norbo »

Regarding the character, did you happen to try all the settings that the demos use to set it up in the CharacterControllerInput class?
Specifically:

Code: Select all

characterController = new CharacterController(Vector3.Zero, 3, .5f, 5, .2f, 1.1f, 50, 70, 6, (float)Math.PI / 4, 5, 3, 2, 5, .1f, (float)Math.PI / 6, (float)Math.PI / 8);
I assume you're using the space.rayCast function; could you copy and paste the whole function call up here? The rayCast takes an origin and a direction instead of two endpoints in case that's what's going on.

CompoundBodies were initially built to be dynamic only. This is currently on the list to be changed in v0.7.1.
goldsword
Posts: 18
Joined: Fri Dec 05, 2008 8:46 pm

Re: Controlled Physics

Post by goldsword »

Yeah I tried alot of different settings with the controller but nothing helped. Basically it worked until you bumped into something and once you bumped into an object you were forced to find unsmooth terrain inorder to get the character to return to grounded state. Maybe changing some terrain collision tweaks could have helped me unsure.

Yes, I pass in an origin and a direction, here is the code:

// get direction of the tracer round
Vector3 d = tracers.direction;

// get velocity
float len = d.Length();

// scale velocity to get velocity change this frame
float l = len * dt;

// normalize direction
d.Normalize();

// BEPU physics out params
BEPUphysics.Entity res;
Vector3 loc;
Vector3 norm;
float toi;

// send a ray using the tracer rounds last position, normalized direction and distance traveled this frame
if (physicalWorld.rayCast(tracers.lastPosition, d, l, true, out res, out loc, out norm, out toi))
{
// hit something...
}


About the compounds, yeah I thought it was something like that, I dont even need dynamic compounds just good to know for the future.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Controlled Physics

Post by Norbo »

What does tracers.direction represent exactly? Judging on how it is used I'd assume it's a velocity previously calculated. Two possibilities come to mind; one is a low velocity used relative to the motion applied, the other is a known bug in v0.7.0's raycast against terrains and static triangle groups where if the origin of the ray isn't in the bounding box of the terrain/static triangle group, it probably won't find any intersections. That second option wouldn't account for any normally added entities missed even if it was happening, though.

One more longshot option would be testing it with the BruteForce broadphase (space.setBroadPhase(new BruteForce())). If it still occurs with this change, it will help me narrow down the issue a bit.

If you have the chance, could you set up a little reproduction case for the character controller problems?
goldsword
Posts: 18
Joined: Fri Dec 05, 2008 8:46 pm

Re: Controlled Physics

Post by goldsword »

tracers.direction represents the velocity yes. What do you mean by low velocity used relative to the motion applied?
When I tried collision against none terrain I pickup the collision everytime UNLESS I'm relatively close to the object?
After some testing I detected this was because the if the raycast detected collision but the TOI was 0 I would not process
that collision because the normal of collision would be zero. That is when firing close to objects (but still not inside them)
the collision is infact detected but without proper data to handle it, any ideas?

BruteForce or not had no impact.

I tried setting up a reprocase but this time the character class would behave just fine, I'm unsure as of way.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Controlled Physics

Post by Norbo »

My concern was that a different (smaller) velocity was being used to raycast compared to the velocity used to actually advance the position of the bullet. This wouldn't have anything to do with the 'up close' issue, though.

A toi of 0 should only occur when the origin of the ray is within the object being tested against (or within its margin if you're including margins in the raycast). Are you currently starting the ray at the edge of the character rather than within the character and using a single hit returning raycast? An alternative would be to use the multiple hit version of the function and start the ray within the character itself. That way, the ray's origin wouldn't be inside another target object (unless the character was inside that target object). Any unwanted hits (against the character itself, for example) could be filtered out of the list to find the first 'real' hit.

Another method would be to simply pick an arbitrary direction to provide a normal in a problem case. The negative velocity direction might be 'good enough.'
goldsword
Posts: 18
Joined: Fri Dec 05, 2008 8:46 pm

Re: Controlled Physics

Post by goldsword »

Ah thanks norbo I'm an idiot, ofcourse I must use a multi ray version since the ray is starting inside the "firing object", that collision is detected first but discarded and once the projectile is outside the firing character im inside the real object thus giving me toi 0. I'll change to multi version right away again thank you! Also you mentioned some known issue with ray against the terrain. Is there anyway to reduce this or work around it?

As of margins, I'm unsure about this concept, first of all why use margins? Second is there a difference between margins and penetration depth? For instance I noticed on objects you can set a certain allow penetration depth, but you can also use different margins... Sorry If I'm dragging this thread along and off topic.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Controlled Physics

Post by Norbo »

The ray-terrain issue should only occur when the ray origin and ray direction * maximumLength location are both outside of the bounding box of the terrain. If your terrain isn't a large flat plane and you're shooting the rays from a character near the ground, this problem probably won't show up too often. A nasty workaround is to make a vertex somewhere on your terrain higher than any other point on the terrain plus the character's height so that no matter where the character is, it's still inside the bounding box.

The margins allow for certain fast collision detection algorithms to be used. Its effect on geometry is like sweeping a sphere with radius equal to the margin across the exterior surface, fattening the shape and smoothing corners. The fallback penetrating-case algorithm doesn't technically need margins, but it isn't quite as accurate as the margin-enabled algorithm.

The allowed penetration is how far an object can be shoved into another object before position correction forces show up. Large values prevent position correction from happening, leading to odd intersections. Very tiny values or 0 can lead to jitter since it is constantly trying to correct the tiniest of penetrations.
fa_
Posts: 2
Joined: Tue Apr 21, 2009 2:13 pm

Re: Controlled Physics

Post by fa_ »

goldsword wrote:I I also removed any rotation by assigning a zero intertia tensor
I need to do the same, but I don't know how... :(
Something like entity.localSpaceInertiaTensor = ???

Thank you
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Controlled Physics

Post by Norbo »

Just about, it's:

(Entity).localSpaceInertiaTensorInverse = Toolbox.zeroMatrix;
fa_
Posts: 2
Joined: Tue Apr 21, 2009 2:13 pm

Re: Controlled Physics

Post by fa_ »

Thank you it works :D
Post Reply