FIXED - SphereCharacterController falling through terrain

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Eclectus
Posts: 20
Joined: Sat Feb 04, 2012 11:22 pm

FIXED - SphereCharacterController falling through terrain

Post by Eclectus »

Hi all,

I've had a look to see if this has already been discussed but not turned up any matches. Here is the situation.

(1) I spawn in some SphereCharacterController Entities, 10m above the terrain:

Code: Select all

    
    _characterController					= new SphereCharacterController();
    _characterController.Body.PositionUpdated	+= OnCharacterMoved;
    _characterController.Body.Radius			= Radius;
    _position.Y							= ComputeAltitude() + INITIAL_DROP_HEIGHT;
    _characterController.Body.Position			= _position;
    PhysicsSpace.Add( _characterController );
(2) They fall downwards through the terrain.

Now if I apply a horizontal impulse, or manually set the LinearVelocity, this does not happen, they land correctly on the terrain:

Code: Select all

_characterController.Body.ApplyImpulse( Vector3.Zero, Vector3.Left );
I understand that setting the Body.Position is functionally teleporting the Entity, but I'm not aware of an alternative to this for setting the 'initial position'. What should I change, to avoid having to supply a spurious LinearVelocity/Impulse?

Thanks in advance, I have tried to title this post in such a way as to attract future attention, should others come across this scenario.
- Eclectus
Last edited by Eclectus on Tue Feb 07, 2012 8:22 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: SphereCharacterController falling through terrain

Post by Norbo »

I understand that setting the Body.Position is functionally teleporting the Entity, but I'm not aware of an alternative to this for setting the 'initial position'. What should I change, to avoid having to supply a spurious LinearVelocity/Impulse?
Teleporting the entity once to put it somewhere initially is perfectly acceptable. Teleporting it repeatedly to control the motion (thus overriding collision response) is what will get into trouble.

That said, nothing there could directly explain why it falls through the ground. The application of an impulse can wake an object up, but if it's falling, it's not asleep. Impulse application's only other direct effect is the modification of velocity which doesn't help explain the lack of fall-through.

Can you reproduce this by modifying a demo in the BEPUphysicsDemos? Being able to debug it would help me diagnose the issue.
Eclectus
Posts: 20
Joined: Sat Feb 04, 2012 11:22 pm

FIXED - Re: SphereCharacterController falling through terrai

Post by Eclectus »

Hi Norbo :)

Thanks for the reply, its good to know that 'initial teleporting' is acceptable. I'm happy to create a repro case with one of the BEPUphysicsDemos, absolutely. Your help is sincerely appreciated!

Btw the terrain is quite large, 1024*1024, with each unit representing 1m, not sure if this is significant. Will work on the repro case, and update the thread if anything else comes to mind relative to this.

Thanks
Eclectus
Last edited by Eclectus on Tue Feb 07, 2012 8:22 pm, edited 1 time in total.
Eclectus
Posts: 20
Joined: Sat Feb 04, 2012 11:22 pm

FIXED - Re: SphereCharacterController falling through terrai

Post by Eclectus »

I woke up this morning knowing what was going wrong (in theory at least) - floating point cracks between triangles! Here is some more code showing my theory, I'm happy to make the Repro as well, let me know if it is wanted, it might be you'll see this and go "ah.....floats!"

Code: Select all

//-------------------------------------------------------------------------------
		private void InitializeCharacterController()
		{
			_characterController                            = new SphereCharacterController();
			_characterController.Body.PositionUpdated       += OnCharacterMoved;
			_characterController.Body.Radius                = Radius;
			_position.Y                                     = ComputeAltitude() + INITIAL_DROP_HEIGHT;

			// Doing this prevents characters from falling through the floor - the
			// terrain heightmap is 1024*1024 meters in size, and my theory is that 
			// floating point errors seem to allow characters to fall 'between' 
			// triangles. This is based on the fact that it only happens  at certain
			// positions, for example "297.0f, y, 120.0f", or "646.0f, y, 941.0f". 
			// Adding the 'avoidCracks' offset below avoids this. A general solution may
			// be to use four 'origin points' of contact internally within 
			// SphereCharacterController to form a triangular pyramid, at least until when the
			// first collision has occurred, but I will defer to Norby's knowledge of the area,
			// there may be other solutions :)
			var avoidCracks								= new Vector3( 0.01f, 0.0f, 0.01f );
			_characterController.Body.Position     = _position + avoidCracks;
			GlobalAccess.ThePhysicsSpace.Add( _characterController );
		}
The code above 'addresses' the floating point issue - all the characters will land correctly on the ground.

I'd like to express my enthusiasm for BEPU (greatly intuitive class structure, wonderful performance, strong and pleasant community). If my theory is correct, then I should emphasize that this is an inherent problem with floating point precision, which would be encountered by any physics system. Let me know if the Repro is still desirable, and I'll make it, with say 256 spheres falling to at 'grid points' above a big piece of terrain.

Gratefully
Eclectus
Last edited by Eclectus on Tue Feb 07, 2012 8:23 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: SphereCharacterController falling through terrain

Post by Norbo »

I was able to reproduce the issue; it turns out there's a problem in the mesh boundary handling system. Under normal circumstances, this system prevents 'bumps' from happening when an object slides between two adjacent triangles. Unfortunately, if a particular type of object lands right on a border in a specific way (like a sphere created right on top of a vertex in a flat terrain), the boundary smoother system will 'smooth away' the contacts erroneously.

I'll try to get a fix into the development fork soon. In the interim, you can disable this system by setting the mesh.ImproveBoundaryBehavior = false.
I'd like to express my enthusiasm for BEPU (greatly intuitive class structure, wonderful performance, strong and pleasant community).
Thanks :)
Eclectus
Posts: 20
Joined: Sat Feb 04, 2012 11:22 pm

FIXED - Re: SphereCharacterController falling through terrai

Post by Eclectus »

Ah this makes sense, I see. I'm very glad my information was useful (should have mentioned that it was only happening on the flat bits of the terrain, I didn't make that connection in my head), I've turned off ImproveBoundaryBehavior on the terrain and it completely fixed that issue, thanks for the guidance :)

Will grab the full fix from the development branch when the time is right for it, this interim fix means it is not urgent.

My only other question would be - I noticed that if I spawn the entities 10m above the ground, they fall and hit it, but if I go with 5m, then they fall through it. I'm not sure why this would occur, they all have the same radius of 0.9m, and I use a raycast to ensure that they are all the appropriate distance above the ground:

Code: Select all

//-------------------------------------------------------------------------------
private float ComputeAltitude()
{
	var fromPosition = _position + new Vector3( 0f, ALTITUDE_RAY_OFFSET, 0f );
	var altitudeRay = new Ray( fromPosition, Vector3.Down );
	RayCastResult result;
	ThePhysicsSpace.RayCast( altitudeRay, ALTITUDE_RAY_LENGTH, out result );

	return result.HitData.Location.Y;
}
Here is how the terrain is set up, perhaps it is missing something? Or maybe the Physics system should receive at least one update before anything gets spawned?

Code: Select all

{
	var terrainShape = new TerrainShape( GroundMiner.GetAltitudeArray(), QuadTriangleOrganization.BottomRightUpperLeft );
	var terrainTransform = new AffineTransform( Vector3.Zero );
	var terrain	 = new Terrain( terrainShape, terrainTransform );
	terrain.CollisionRules.Group = BepuCollisionRules.StaticLevelGroup;

	// We turn this off, as an interim measure to fix characters directly over vertices on flat terrain falling through
	terrain.ImproveBoundaryBehavior = false;

	terrain.Thickness = 1f;
	terrain.UpdateBoundingBox();
	ThePhysicsSpace.Add( terrain );
}
All suggestions/ideas welcomed - I feel its important to follow all best practices when using a system
Eclectus
Last edited by Eclectus on Tue Feb 07, 2012 8:23 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: SphereCharacterController falling through terrain

Post by Norbo »

That should not happen unless the gravity is extremely high relative to the size of the character and the character's continuous collision detection was manually disabled. If CCD was manually disabled by setting the character body's PositionUpdateMode to something other than Continuous, the character would need to be falling at a rate of over 114 units per second upon impact given that amount of thickness and character radius and a standard timestep of 1/60f. This would require an immense gravity, so it doesn't seem likely.

I don't see anything in the set up that would be responsible, and the space does not need to be updated first or anything like that. The terrain.UpdateBoundingBox() is superfluous though.

I am unable to be able to reproduce the issue; a demo might be useful again :)
Eclectus
Posts: 20
Joined: Sat Feb 04, 2012 11:22 pm

FIXED - Re: SphereCharacterController falling through terrai

Post by Eclectus »

Good news!

I have discovered what was failing - it was my ComputeAltitude() method. The raycast is completely ignoring the terrain, and 99% sure this is related to something I've done in the way that the terrain is set up, or that I should use a CollisionFilter in the raycast. Will dig in and post what I find, it may be of use to some else following the thread. More detailed response once I know more.

Eclectus
Last edited by Eclectus on Tue Feb 07, 2012 8:24 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: SphereCharacterController falling through terrain

Post by Norbo »

A fix for the previous issue has been uploaded to the development fork: http://bepuphysics.codeplex.com/SourceC ... evelopment
Eclectus
Posts: 20
Joined: Sat Feb 04, 2012 11:22 pm

FIXED - Re: SphereCharacterController falling through terrai

Post by Eclectus »

Hi, thanks for the update it completely fixed issue #1 :)

Regarding the RayCasts issue I have looked into it deeply, and can code a full repro demo if needed. However the new information that I've gained may be enough:

* When I'm creating the Terrain I'm using a TerrainShape:

Code: Select all

var terrainShape	  = new TerrainShape( GroundMiner.GetAltitudeArray(), QuadTriangleOrganization.BottomRightUpperLeft );
var terrainTransform = new AffineTransform( Vector3.Zero );
var terrain          = new Terrain( terrainShape, terrainTransform );
* This will fail to be hit by RayCasts from above.

* If I change the above to use QuadTriangleOrganization.BottomLeftUpperRight then all will be well, and the raycasts to the terrain (also from above) will work perfectly. My theory is that the normals are pointing the wrong way?

* Taking this theory further, I'm guessing that terrain only has 'one sided' collision, so that if something penetrates it, it can push its way back through without being obstructed?

Thanks in advance :)
Eclectus
Last edited by Eclectus on Tue Feb 07, 2012 8:23 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: SphereCharacterController falling through terrain

Post by Norbo »

That's interesting- I looked around and found something which would be problematic when a raycast occurs right at the boundary between triangles in a quad. Ray casts right on vertices fail under one organization but not the other because of how it picks which quad to test. Under BottomRightUpperLeft, both triangles are hit. Under BottomLeftUpperRight, only one triangle can be hit.

I've uploaded the fix to the development version again.

Thanks for testing these corner cases out :)
I'm guessing that terrain only has 'one sided' collision, so that if something penetrates it, it can push its way back through without being obstructed?
That is correct.
Eclectus
Posts: 20
Joined: Sat Feb 04, 2012 11:22 pm

Re: FIXED - SphereCharacterController falling through terrai

Post by Eclectus »

This is all working perfectly now, with the latest development version, and I have marked all my posts as "FIXED" - so that anyone looking in this area will be aware that it is all resolved.

Thanks for resolving this so quickly, I'd expected any potential changes to take much longer, but instead it happened in a much more agile way. Testing the corner cases out was fun - felt like a mental 'run on the treadmill' :) and I enjoy the opportunity to contribute to the big picture. Using BEPU is fun!

Cheers
Eclectus
Post Reply