xexuxjy / bullet-xna

Automatically exported from code.google.com/p/bullet-xna
Other
21 stars 5 forks source link

Collision with the HeightfieldTerrainShape and CapsuleShapeZ objects never clears. #1

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. My Coordinate space is X(forward), Y (side), Z(up) (units are meters)
2. The HeightField is set to use upaxis 2(Z) and a byte[] of 256x256 floats in 
(y * 256) + x form.   All floats are 21m.
3. Dropping a RigidBody with a CapsuleShapeZ as it's collision shape onto the 
heightfield results in a perpetual collision until the heightfield is recreated.

What version of the product are you using? On what operating system?
r6 using monoxna for an XNA library substitute.

Please provide any additional information below.

Original issue reported on code.google.com by dcoliva...@gmail.com on 7 Apr 2011 at 5:13

GoogleCodeExporter commented 9 years ago
The issue goes away when I disable persistency  by un-commenting and converting 
the line 179 in ConvexConcaveCollisionAlgorithm.   The line previously read:
//m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);

end result line look like:
m_dispatcher.ClearManifold(m_convexTriangleCallback.m_manifoldPtr);

That firmly lays the fault in persistency/PersistentManifold.   I expect that 
disabling persistency in ConvexConcave has detrimental results performance wise.

Original comment by dcoliva...@gmail.com on 9 Apr 2011 at 4:40

GoogleCodeExporter commented 9 years ago
Hiyas,

Do you have a demo project I can use to try this please?
Is the issue just with CapsuleZ or the other Capsule (or other collision 
shapes)?
I'm looking at adding an object pool for ManifoldPoints as that's one of the 
worse culprits for allocations. I'll do some more tests with persistency 
enabled/disabled.

Thanks

Original comment by xexu...@gmail.com on 11 Apr 2011 at 8:22

GoogleCodeExporter commented 9 years ago
I have more like a demo client server....   application :).      A while back, 
I wrote a C# pInvoke lib for bullet and worked it into a physics plugin for a 
3d simulator that I work on called OpenSimulator.  The pInvoke version got the 
job done but it was extremely hard to use and debug.  I'm using the plugin code 
I wrote for that now to test the library. If you'd like I could provide you 
with a link to a source/precompiled version privately.    It isn't a public 
release yet so it isn't something that I want to distribute publically until 
it's at least as featureful as the ODE Physics engine plugin that is the 
current default.   There's a bit more to trying it out then running the program 
because it's really just a group of services that when combined with a properly 
configured client side render/viewer program results in a virtual world over a 
network with server side physics.

Original comment by dcoliva...@gmail.com on 11 Apr 2011 at 9:22

GoogleCodeExporter commented 9 years ago
Np, I'll try and create a test project based on the info above and get back to 
you if I'm struggling to re-create it.

thanks

Original comment by xexu...@gmail.com on 11 Apr 2011 at 10:12

GoogleCodeExporter commented 9 years ago
We'll see if this renders correctly in google code.
This is the code that creates the heightfield.

using btVector3 = Microsoft.Xna.Framework.Vector3;

public override void SetTerrain(float[] heightMap)
{
      uint Constants.RegionSize = 256;
      if (m_terrainShape != null)
          DeleteTerrain();

      float hfmax;
      float hfmin;

      _origheightmap = heightMap;

      hfmin = 0;
      hfmax = 256;
      byte[] bmap = new byte[heightMap.Length*4];
      int bmappos = 0;
      for (int i=0;i<heightMap.Length;i++)
      {
          byte[] val = BitConverter.GetBytes(heightMap[i]);
          for (int j=0;j<val.Length;j++)
          {
               bmap[bmappos++] = val[j];
          }
      }

      m_terrainShape = new HeightfieldTerrainShape((int)Constants.RegionSize, (int)Constants.RegionSize, bmap,
                                                           1.0f, hfmin, hfmax, 2,
                                                           PHY_ScalarType.PHY_FLOAT, false);
      float AabbCenterX = Constants.RegionSize/2f;
      float AabbCenterY = Constants.RegionSize/2f;

      float AabbCenterZ = 0;
      float temphfmin, temphfmax;

      temphfmin = hfmin;
      temphfmax = hfmax;

      if (temphfmin < 0)
      {
          temphfmax = 0 - temphfmin;
          temphfmin = 0 - temphfmin;
      }
      else if (temphfmin > 0)
      {
          temphfmax = temphfmax + (0 - temphfmin);

       }
       AabbCenterZ = temphfmax/2f;

       m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ);

       m_terrainTransform = Matrix.CreateTranslation(m_terrainPosition);

       m_terrainMotionState = new DefaultMotionState(m_terrainTransform, Matrix.Identity);
       TerrainBody = new RigidBody(0, m_terrainMotionState, m_terrainShape, VectorZero);
       TerrainBody.SetUserPointer((IntPtr)0);
       m_world.AddRigidBody(TerrainBody);
}

Original comment by dcoliva...@gmail.com on 11 Apr 2011 at 11:08

GoogleCodeExporter commented 9 years ago
And, here's the capsule Creator.   Note, that in the ODE Plugin we're using an 
Angular motor to cause the capsule to stand on it's end.  In bullet we're using 
a Generic6DofConstraint to keep the capsule standing on end.  The issue occurs 
with, or without the constraint.

Using btVector3 = Microsoft.Xna.Framework.Vector3;
Using btQuaternion = Microsoft.Xna.Framework.Quaternion;

 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
 {

     if (CAPSULE_LENGTH <= 0)
     {
         m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid!  Setting it to the smallest possible size!");
          CAPSULE_LENGTH = 0.01f;

     }

     if (CAPSULE_RADIUS <= 0)
     {
          m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid!  Setting it to the smallest possible size!");
          CAPSULE_RADIUS = 0.01f;

     }

     Shell = new CapsuleShapeZ(CAPSULE_RADIUS, CAPSULE_LENGTH);

     // Copy OpenMetaverse.Vector3 to Microsoft.Xna.Framework.Vector3
     m_bodyPosition.X = npositionX;
     m_bodyPosition.Y = npositionY;
     m_bodyPosition.Z = npositionZ;

     m_CapsuleOrientationAxis = new btVector3(1, 0, 1);
     m_bodyOrientation = new btQuaternion(m_CapsuleOrientationAxis, (Utils.DEG_TO_RAD * 90));
     m_bodyOrientation.Normalize();

     // This used to be a btTransform
     //m_bodyTransform = new btTransform(m_bodyOrientation, m_bodyPosition);)

     m_bodyTransform = Matrix.CreateFromQuaternion(m_bodyOrientation);
     m_bodyTransform.Translation = m_bodyPosition;

     if (m_bodyMotionState == null)
         m_bodyMotionState = new DefaultMotionState(m_bodyTransform, Matrix.Identity);
     else
         m_bodyMotionState.SetWorldTransform(m_bodyTransform);

     m_mass = Mass;

     Body = new btRigidBody(m_mass, m_bodyMotionState, Shell,btVector3.Zero);

     // this is used for self identification.
     Body.SetUserPointer(this);  // "this" is of type BulletXnaPlugin.BulletXnaCharacter

     // Used to detect whether or not the proxy is standing on something
     ClosestCastResult = new ClosestNotMeRaycastResultCallback(Body);  

     m_parent_scene.AddRigidBody(Body);

     // Since this is a users character proxy, we are disabling the automatic deactivation.
     Body.SetActivationState(ActivationState.DISABLE_DEACTIVATION);

     if (m_aMotor != null)
     {

          m_parent_scene.getBulletWorld().RemoveConstraint(m_aMotor);
          m_aMotor = null;
     }

     m_aMotor = new Generic6DofConstraint(Body, m_parent_scene.TerrainBody,
                                                                         ref m_parent_scene.TransZero,
                                                                         ref m_parent_scene.TransZero, false);
     m_aMotor.SetAngularLowerLimit(btVector3.Zero);
     m_aMotor.SetAngularUpperLimit(btVector3.Zero);

}

Original comment by dcoliva...@gmail.com on 11 Apr 2011 at 11:21

GoogleCodeExporter commented 9 years ago
anyway..   the result is....... the contact that occurred continues to apply 
contact resolution force each step regardless of whether or not the CapsuleZ is 
still in contact with the heightfield.   

The world startup:

 m_broadphase = new AxisSweep3Internal(ref worldAabbMin, ref worldAabbMax, 0xfffe, 0xffff, 16384, null, false);
m_collisionConfiguration = new DefaultCollisionConfiguration();

m_solver = new SequentialImpulseConstraintSolver();
m_dispatcher = new CollisionDispatcher(m_collisionConfiguration);

m_world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, 
m_collisionConfiguration);
m_world.SetGravity(ref m_gravity);

gravity is -9.8m/s

the world is stepped with:
public const float WorldTimeComp = 1/60f;

timeStep is updated in the loop SinceLastFrame.TotalSeconds where there are 10 
loops per second when the simulator is running efficiently.

m_world.StepSimulation(timeStep, 10, WorldTimeComp);

Original comment by dcoliva...@gmail.com on 11 Apr 2011 at 11:36

GoogleCodeExporter commented 9 years ago
Haven't got a full re-creation of your test bed yet, but I put a simpler 
version together and a comparison to the standard bullet code. Noticed there 
was a line missing in ConvexConcaveCollisionAlgorithm which meant it wasn't 
refreshing contact points. Can you try the latest revision of this class and 
see if it fixes your issue?

ta.

Original comment by xexu...@gmail.com on 13 Apr 2011 at 10:34

GoogleCodeExporter commented 9 years ago
Success.  That fixes it.  Thanks

Original comment by dcoliva...@gmail.com on 14 Apr 2011 at 12:21

GoogleCodeExporter commented 9 years ago

Original comment by xexu...@gmail.com on 14 Apr 2011 at 6:15

GoogleCodeExporter commented 9 years ago
How do I create bullet dlls for P/Invokes?  I have tried with no success.  I 
only successfully compiled LinearMath as a dll - all the others gave me 
unresolved external symbol.

Original comment by superfoo...@gmail.com on 25 Aug 2011 at 3:39

GoogleCodeExporter commented 9 years ago
You must create a wrapper shared library with public static and exported 
methods.   

Original comment by dcoliva...@gmail.com on 25 Aug 2011 at 5:13