Strange physics object movement
Strange physics object movement
I recently noticed the physics objects in our game will sometimes start moving around in a very strange, random way. As a test, I made a spawner for a simple Box entity: new Box(pickInfo.HitLocation + Vector3.UnitY, 10, 10, 10, 50). Most of the boxes spawned will simply float up from the surface and come to a stop. But every once in a while one will spawn and then begin rolling and spinning around randomly for a good 10 to 15 seconds. The way it rolls, it seems like the center of mass is at a corner or even outside of the box. And its not acting as if it suddenly had a large force applied to it once and then spins out of control, it rolls around fairly slowly. It only seems to happen with Boxes, I wasn't able to reproduce it with Spheres and it only seems to happen if the box is spawned partially inside the StaticMesh terrain. I can make a video of it if it'll help.
This didn't used to be an issue before and I'm not sure why it suddenly started happening. I tried rendering the boxes and terrain using the debug renderer, and the motion still doesn't make sense. I'm pretty sure there are no external forces being applied. Do you have any ideas of what could be causing this Norbo?
This didn't used to be an issue before and I'm not sure why it suddenly started happening. I tried rendering the boxes and terrain using the debug renderer, and the motion still doesn't make sense. I'm pretty sure there are no external forces being applied. Do you have any ideas of what could be causing this Norbo?
Re: Strange physics object movement
A low confidence guess would be that some contacts are incorrectly persisting. The most likely candidate would be the triangle-convex 'internal sphere' protective contact, just because they're probably the strangest thing that happens during deep convex-mesh penetration.
A video might help, but if the behavior is as strange and apparently causeless as the description implies, I'm guessing the only thing that will truly narrow it down would be a reproduction in the latest demos for me to debug directly. If you could make one for me, it would help a lot.
A video might help, but if the behavior is as strange and apparently causeless as the description implies, I'm guessing the only thing that will truly narrow it down would be a reproduction in the latest demos for me to debug directly. If you could make one for me, it would help a lot.
Re: Strange physics object movement
I've managed to reproduce it in the demo framework for the build I'm using in my game, but I can't manage to reproduce it on the latest demo framework. I'm using sharpdx, so the last build I have is from commit 87fc56cc9ed4. Do you still want me to upload the demo?
Re: Strange physics object movement
That's up to you; I might be able to verify that it was fixed in the latest version and potentially tell you a trivial workaround (like copying a particular updated file). I've still got a bit of a backlog of work piled up, so a proper multifork release of v1.3.0 isn't imminent; you might have to wait a while for an 'official' sharpdx fork fix.
Re: Strange physics object movement
Ok well here's the demo for the sharpdx fork. It loads up some files and generates StaticMeshes to recreate the terrain. I've attached the mesh files to this post. Extract them to a Mesh folder in the project output directory. Use the left mouse button to spawn boxes where the camera is looking. It usually takes several tries but eventually some of them will start rolling around weirdly.
Code: Select all
using System;
using System.IO;
using BEPUphysics;
using BEPUphysics.Collidables;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics.Settings;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Vector3 = SharpDX.Vector3;
namespace BEPUphysicsDemos.Demos
{
/// <summary>
/// Demo showing a wall of blocks stacked up.
/// </summary>
public class WallDemo : StandardDemo
{
/// <summary>
/// Constructs a new demo.
/// </summary>
/// <param name="game">Game owning this demo.</param>
public WallDemo(DemosGame game)
: base(game)
{
foreach(var file in Directory.EnumerateFiles("Mesh"))
{
using(var reader = new BinaryReader(File.OpenRead(file)))
{
var vertCount = reader.ReadInt32();
var vertexBytes = reader.ReadBytes(vertCount);
var indexCount = reader.ReadInt32();
var indexBytes = reader.ReadBytes(indexCount);
var vertexFloats = new float[vertCount / sizeof(float)];
var vertices = new Vector3[vertexFloats.Length / 3];
var indices = new int[indexCount / sizeof(int)];
Buffer.BlockCopy(vertexBytes, 0, vertexFloats, 0, vertCount);
Buffer.BlockCopy(indexBytes, 0, indices, 0, indexCount);
for(var i = 0; i < vertexFloats.Length; i += 3)
vertices[i / 3] = new Vector3(vertexFloats[i], vertexFloats[i + 1], vertexFloats[i + 2]);
var mesh = new StaticMesh(vertices, indices);
Space.Add(mesh);
game.ModelDrawer.Add(mesh);
}
}
var box = new Box(new Vector3(0, 1250, 0), 100, 5, 100);
Space.Add(box);
Space.Remove(kapow);
Space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0f) * 10 * 2.5f;
Space.ForceUpdater.TimeStepSettings.TimeStepDuration = 1 / 33f;
Space.ForceUpdater.TimeStepSettings.MaximumTimeStepsPerFrame = 3;
ConfigurationHelper.ApplyScale(10f);
CollisionResponseSettings.PenetrationRecoveryStiffness = 0.4f;
game.Camera.Position = new Microsoft.Xna.Framework.Vector3(0, 1300, 0);
game.Camera.Speed = 100;
}
private MouseState prevMouseState;
public override void Update(float dt)
{
if(Game.MouseInput.LeftButton == ButtonState.Pressed && prevMouseState.LeftButton == ButtonState.Released)
{
RayCastResult hit;
var pos = Game.Camera.Position;
var forward = Game.Camera.WorldMatrix.Forward;
if(Space.RayCast(new SharpDX.Ray(new Vector3(pos.X, pos.Y, pos.Z), new Vector3(forward.X, forward.Y, forward.Z)), 100, out hit))
{
var box = new Box(hit.HitData.Location + Vector3.UnitY, 10, 10, 10, 50);
Space.Add(box);
Game.ModelDrawer.Add(box);
}
}
base.Update(dt);
prevMouseState = Game.MouseInput;
}
/// <summary>
/// Gets the name of the simulation.
/// </summary>
public override string Name
{
get { return "Wall"; }
}
}
}
- Attachments
-
- Mesh.rar
- (1.44 MiB) Downloaded 459 times
Re: Strange physics object movement
I'm not sure I was actually able to reproduce it (in hindsight, that video would have been a good idea indeed
).
I did catch a couple of instances where the internal sphere protective contact caused some issues. It manifests as a sort of invisible supporting object right on the bottom of the box, lifting its middle away from the ground. The box usually ends up tilting to one side or another. It may roll slightly if it starts in an unstable configuration.
There was also some general contact instability. You should get a noticeable improvement in behavior by using a more modern variant of the ConfigurationHelper.ApplyScale:
The above would require Toolbox.Epsilon and Toolbox.BigEpsilon to be static rather than const.
You may want to experiment with other values for the scale, too. Since the gravity is 25 times the 'regular' value, a scale of 25 might work better than 10.
With these newer settings, I didn't notice anything weird happening during a few minutes worth of testing.

I did catch a couple of instances where the internal sphere protective contact caused some issues. It manifests as a sort of invisible supporting object right on the bottom of the box, lifting its middle away from the ground. The box usually ends up tilting to one side or another. It may roll slightly if it starts in an unstable configuration.
There was also some general contact instability. You should get a noticeable improvement in behavior by using a more modern variant of the ConfigurationHelper.ApplyScale:
Code: Select all
/// <summary>
/// Scales the configuration settings for collision detection and response to handle
/// a different scale interpretation. For example, if you want to increase your gravity to -100 from -10 and consider a 5 unit wide box to be tiny,
/// apply a scale of 10 to get the collision response and detection systems to match expectations.
/// </summary>
/// <param name="space">Space to configure.</param>
/// <param name="scale">Scale to apply to relevant configuration settings.</param>
public static void ApplyScale(Space space, float scale)
{
//Set all values to default values * scale.
space.DeactivationManager.VelocityLowerLimit = 0.26f * scale;
CollisionResponseSettings.MaximumPenetrationCorrectionSpeed = 2 * scale;
CollisionResponseSettings.BouncinessVelocityThreshold = 1 * scale;
CollisionResponseSettings.StaticFrictionVelocityThreshold = .2f * scale;
CollisionDetectionSettings.ContactInvalidationLength = .1f * scale;
CollisionDetectionSettings.ContactMinimumSeparationDistance = .03f * scale;
CollisionDetectionSettings.MaximumContactDistance = .1f * scale;
CollisionDetectionSettings.DefaultMargin = .04f * scale;
CollisionDetectionSettings.AllowedPenetration = .01f * scale;
//Adjust epsilons, too.
Toolbox.Epsilon = 1e-7f * scale;
Toolbox.BigEpsilon = 1e-5f * scale;
MPRToolbox.DepthRefinementEpsilon = 1e-4f * scale;
MPRToolbox.RayCastSurfaceEpsilon = 1e-9f * scale;
MPRToolbox.SurfaceEpsilon = 1e-7f * scale;
PairSimplex.DistanceConvergenceEpsilon = 1e-7f * scale;
PairSimplex.ProgressionEpsilon = 1e-8f * scale;
//While not fully a size-related parameter, you may find that adjusting the SolverSettings.DefaultMinimumImpulse can help the simulation quality.
//It is related to 'mass scale' instead of 'size scale.'
//Heavy or effectively heavy objects will produce higher impulses and early out slower, taking more time than needed.
//Light or effectively light objects will produce smaller impulses and early out faster, producing a lower quality result.
}
You may want to experiment with other values for the scale, too. Since the gravity is 25 times the 'regular' value, a scale of 25 might work better than 10.
With these newer settings, I didn't notice anything weird happening during a few minutes worth of testing.
Re: Strange physics object movement
Hmm, I'm still able to reproduce it after having applied the suggested fixes. Heres a video of it:
Re: Strange physics object movement
Now that is strange- I never saw anything like that, and I have no idea what would cause it. Is it rare enough that I could have missed it after about 10 minutes of spawning boxes all over the place?
Re: Strange physics object movement
It's not that rare. I can usually get it to happen within a minute or two. It only took me 40s to get it to happen that time. The box just needs to be spawned intersecting the StaticMesh
Re: Strange physics object movement
I tried another ~5,000 boxes, but every one seemed to work as expected.
I don't have any good theories for why you would see different behavior than me. The behavior in the video almost looks like the coefficient of friction is negative.
At this point, I suspect gremlins.
I don't have any good theories for why you would see different behavior than me. The behavior in the video almost looks like the coefficient of friction is negative.
At this point, I suspect gremlins.
Re: Strange physics object movement
Hmm, well I think I know why that is: I updated my sharpdx version. When I switched back to the version the demo shipped with, the issue seems to go away (the boxes still sometimes do a backflip on spawning but its no where near as crazy as before). That would explain why this bug suddenly appeared despite nothing changing with the physics in our game... I'm using the latest 2.5 dev package of sharpdx if you want to try it. I was using 2.4.2 previously with no problems I believe. It seems to be something that changed since then. I really don't know how I would go about debugging this, so I'm kind of hoping you have some ideas 

Re: Strange physics object movement
Apparently SharpDX changed the Quaternion.Multiply to be consistent with XNA. Previously, it used the opposite order such that SharpDX's Quaternion.Multiply was XNA's Quaternion.Concatenate.
The problem should go away if you change QuaternionEx.Multiply(a,b) to call Quaternion.Multiply(a,b) and QuaternionEx.Concatenate(a,b) to call Quaternion.Multiply(b,a).
The problem should go away if you change QuaternionEx.Multiply(a,b) to call Quaternion.Multiply(a,b) and QuaternionEx.Concatenate(a,b) to call Quaternion.Multiply(b,a).
Re: Strange physics object movement
Well that fixed it! Sneaky breaking changes... Thanks for the help Norbo