GS3 and other questions...

Dec 14, 2008 at 7:15 PM
I am trying to integrate your physics into a game I am currently working on.

So far I am very impressed it does all I was hoping for...but ...as always once you see your code running...you get more ideas :)

Here a couple questions:

GS3 has been released, are you planning on moving your Oops framework to this version of XNA?
They did a LOT of tuning and I see a couple things in your code that they put into the framework (Quaternion stuff and math helpers).

I found a lot of TODOs in your code...are you still planning on doing them :)? I have not seen activity here since May 23 2008 and your last release if from February. Just checking ...

REFERENCE_COLLISIONS...can you explain why you made this optional?

Removing Objects from the Space:
It looks like there is no "clean" way of removing objects from the Quad. At least so far I have not found any.
Can you maybe provide a QuadTree "Kill Object" method that cleans up all the corresponding data (Collision data, shapes etc), or point me to the code that I can use (in case I did not see it)?

My game is a 6 player split screen game. I need a different physics engine for each player. So far my attempts to do so resulted in a complete performance breakdown. Do you have some tips for using your engine with multiple split-screens? (i.e. one physics---multiple spaces QuadTrees or else)

I am going to run you code against a couple profilers to see where it could be further optimized since it looks like it does not scale out enough.

Thanks for your great work! Physics makes such a big difference for games

Cheers,
Chris
Coordinator
Dec 16, 2008 at 9:15 PM
Hi Chris,

Thanks for trying out my physics code in your game.  I'll try to be as helpful as I can.  Here are some answers to your questions:

- I have a GS3 version of the code almost ready to go.  During my lack of updates here, I have learned quite a bit more about physics and dynamics.  Read a couple books.  Wrote some code.  I've been postponing the update here just because the game I've been writing has been my priority.  I still plan to release my new version soon...er or later.  I'll try to make it sooner.

- Many of the TODOs  have been resolved in the new version.

- I made REFERENCE_COLLISIONS optional just be cause I wanted to swith between them to test if the change was beneficial.  From what I can tell, it is so you should make sure REFERENCE_COLLISIONS is added as a compiler constant.

- There is a QuadTree<T>.Remove method to remove items from the quad-tree.  Is that not working?

- I've learned quite a bit in the area of performance that may help with your game.  The newer version can use a Sweep and Prune method for space-partitioning, can run entirely in a different thread (this would be huge in your case) and has better collision handling for boxes.  There is also quite a bit of performance tuning throughout like inlining and direct type casting.  Things like that.

If you can explain you game's use of the physics in a little more detail, I might be able to help with the performance issues.  What CollisionShape types are you using mostly?  How many shapes are in the game at one time normally?  XBox or Windows? 

Good luck!
Dec 16, 2008 at 10:40 PM
I look forward to see your new version. I will not tune anything for now and focus on my game play.

My game mostly deals with Spheres and sphere collisions that I have to handle.

Its for PC, XBox360 and Zune (Zune in 2D - I still use 3D physics but render all objects in 2D).

So far I found everything I needed in your engine except good support for >1 player split screen instantiation.
Right now I do not use your Physics as a GameComponent but rather update it manually. Not sure what implication that has.
Since I do want to run the physics on one dedicated thread (I have 3 already: Maingame, AI, Networking) I need to find a way to "share" the physics between all 6 players (4 player split plus 2 via Live or AI).

If you have any code / preview of your GS3 engine, I would be very happy to look at it and give you feedback.

my main website is www.c-labs.com there are some old games of me on the site.

you can reach me directly at chrism@c-labs.com

Cheers,
Chris
Coordinator
Dec 18, 2008 at 12:33 AM
As far as split screen support, you could add multiple Camera instances to the ViewpointComponent, each with a different Viewport and View and Perspective matrices.  Then, when rendering, iterate on ViewpointComponent.Cameras and set the relevant GraphicDevice and Effect properties before drawing each split screen.  Not completely elegant but might work satisfactory.

Calling Update manually on the PhysicsComponent is completely fine.  It will also run entirely on a different thread if your careful about what occurs in the ICollisionCallback, IQuadreeComparer and IPhysicIntegator implementations.  Here's some format-mangled code for an asynchronous game component:



#if ASYNC
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using System.Threading;

namespace Oops.Xna.Framework
{
 /// <summary>
 /// Allows for asynchronous updating on game components.
 /// </summary>
 public interface IAsyncUpdateable : Microsoft.Xna.Framework.IUpdateable
 {
  /// <summary>
  /// Starts an asynchronous update.
  /// </summary>
  /// <param name="gameTime">Snapshot of the game's timing state.</param>
  void BeginUpdate(Microsoft.Xna.Framework.GameTime gameTime);

  /// <summary>
  /// Ends an asynchronous update.
  /// </summary>
  void EndUpdate();
 }

 /// <summary>
 /// A class that extends the Microsoft.Xna.Framework.GameTime class with write-enabled
 /// properties.
 /// </summary>
 public class AsyncGameTime
 {
  internal AsyncGameTime() { }

  public TimeSpan ElapsedGameTime { get; set; }
  public TimeSpan ElapsedRealTime { get; set; }
  public bool IsRunningSlowly { get; set; }
  public TimeSpan TotalGameTime { get; set; }
  public TimeSpan TotalRealTime { get; set; }
 }

 /// <summary>
 /// A game component that enables asynchronous updates.
 /// </summary>
 public abstract class AsyncGameComponent : GameComponent, IAsyncUpdateable
 {
#if XBOX
  private int processorAffinity = 4;
#endif
  private volatile bool disposed;

  private AutoResetEvent beginEvent = new AutoResetEvent(false);
  private ManualResetEvent completedEvent = new ManualResetEvent(true);

  private Thread thread;
  private AsyncGameTime gameTime = new AsyncGameTime();

  private bool initialized;

  /// <summary>
  /// Initializes a new instance of the <see cref="AsyncGameComponent"/> class.
  /// </summary>
  /// <param name="game">A <see cref="Microsoft.Xna.Framework.Game"/> that the game component should be attached to.</param>
  public AsyncGameComponent(Game game)
   : base(game)
  {
   // Make sure this component does not get synchronously updated.
   this.Enabled = false;
  }
#if XBOX
  /// <summary>
  /// Gets or set the processor affinity of the running thread.
  /// </summary>
  public int ProcessorAffinity
  {
   get { return this.processorAffinity; }
   set { this.processorAffinity = value; }
  }
#endif
  protected override void Dispose(bool disposing)
  {
   try
   {
    // Make sure the following only occurs once.
    if (!this.disposed)
    {
     // Signal the exit event.
     this.disposed = true;
     this.beginEvent.Set();

     // Wait for the thread to abort.
     if (this.thread != null)
     {
      this.thread.Join();
     }
    }
   }
   finally
   {
    // Call inherited method.
    base.Dispose(disposing);
   }
  }

  public override void Initialize()
  {
   // Call inherited method.
   base.Initialize();

   // Make sure the following only occurs once.
   if (!this.initialized)
   {
    // Start the thread.
    this.thread = new Thread(delegate()
    {
#if XBOX
     // Set the processor affinity.
     Thread.CurrentThread.SetProcessorAffinity(this.processorAffinity);
#endif
     // Wait until signaled to start updating or to exit.  An exit event will terminate the thread.
     while (this.beginEvent.WaitOne() && !this.disposed)
     {
      // Update this component.
      this.Update(this.gameTime);

      // Signal completion.
      this.completedEvent.Set();
     }
    });
    this.thread.Start();

    // This component is initialized.
    this.initialized = true;
   }
  }

  /// <summary>
  ///
  /// </summary>
  /// <param name="gameTime"></param>
  public sealed override void Update(GameTime gameTime)
  {
   throw new NotSupportedException();
  }

  /// <summary>
  /// An overloaded method that allows asynchronous updating.
  /// </summary>
  /// <param name="gameTime">Snapshot of the game's timing state.</param>
  protected abstract void Update(AsyncGameTime gameTime);

  #region IAsyncUpdateable Members

  /// <summary>
  ///
  /// </summary>
  /// <param name="gameTime"></param>
  public virtual void BeginUpdate(Microsoft.Xna.Framework.GameTime gameTime)
  {
   // Wait until signaled that a previous update has completed or if the thread has/will exit.
   if (this.completedEvent.WaitOne() && !this.disposed)
   {
    // Not completed anymore.
    this.completedEvent.Reset();

    // Hold onto the game time for other thread.
    this.gameTime.TotalRealTime = gameTime.TotalRealTime;
    this.gameTime.ElapsedRealTime = gameTime.ElapsedRealTime;
    this.gameTime.TotalGameTime = gameTime.TotalGameTime;
    this.gameTime.ElapsedGameTime = gameTime.ElapsedGameTime;
    this.gameTime.IsRunningSlowly = gameTime.IsRunningSlowly;

    // Signal the other thread to process.
    this.beginEvent.Set();
   }
  }

  /// <summary>
  ///
  /// </summary>
  public virtual void EndUpdate()
  {
   // Wait until the update is complete.  This won't block if an update was never started.
   this.completedEvent.WaitOne();
  }

  #endregion
 }
}
#endif



If you inherit PhysicsComponent from the class above, set the PhysicComponent.Multithreaded to false and change the gameTime parameter of the PhysicComponent.Update method to be of type AsyncGameTime, you can run the entire update on another thread.  To use, just do something like this in you update logic:

...
// Wait for the physics process to finish for the previous frame.
this.phyics.EndUpdate();

// TODO : Access to any physics resources are thread-safe here.
...

// Start the physics process for the current frame.  Call as soon as possible after the EndUpdate.
this.physics.BeginUpdate(gameTime);

...or you can just wait for the next source code check-in.  I would definitely like feedback on the new version of the framework.  I'll work on getting it ready to check-in at CodePlex.  I would estimate that it will be up near the end of this year.

Also, having 6 players all with there own physics space is possible, I think.  I haven't tried but, you could have a QuadTree for each player, adding only the CollisionShape instances relevant for that player in his/her associated quadtree.  Then, call Update and Compare of all the quadtrees in the ICollisionGenerator.Generate method.  So, the integration and collision resolution would still be processed all together but the collision detection would happen in each space.  For the newer version we can re-discuss.  It may be easier.
Dec 18, 2008 at 2:30 AM
Thanks...that looks quite interesting!

My game lives off the collisions between spheres. So most of my gamecode is running actually in your "OnCollided" and the "IPhysicsIntegrator.Integrate" callbacks.
I have to experiement with your ansynchronous class to see what design works best.

I do have the AI on a different thread that needs to access the physics parameter at some point. Therefor its possible that I keep the basic Physics in my GameScreen (hosting all 6 splits), leave the class as multithreaded and process 6 QuadTrees as you described.

Regarding the Camera view I already do have that all setup by instantiating my game class as many times as do have players. I might migrate though to one large space where each player has its confined area but theoretically its possible to shoot a sphere from one playfield into another.

If you have watched the Table Tennis Olympics, you will know what I mean...each game has its own camera and separators but they were all in the same gymn. If one player hit too hard, the table tennis ball might have jumped into another playfield.

From a physics side, I do not want to process the whole "gymn" with one QuadTree but 6 of them...still I would need a "cross over" path from one quadtree into the other.

One more question, if a ball leaves the space (Quadtree) is it deleted automatically? If so, can I get a callback for that?

thanks for your great support
Dec 20, 2008 at 3:32 AM
I just did some testing on the XBox and found out that the physics framework drops down to 2 FPS (from over 500 on the PC).

Since XBox is based on the NETCF there are some things, that are drastic performance problems that need to be avoided:

+ Reflection...very slow if you do GetType() ...
+ Boxing (Value type conversions)
+ Dynamic Lists of any kind (also an additional memory problem)

Are you tuning your new version against these things as well?
I dont want to start tuning until I get your changes ..otherwise we might do the same work :)

On the reflection part: It is very good readable to do the collision with collision (sub) shapes....but unfortunately not very performing.
I am using a simple byte enum to determine the shape type...the code is a bit more complex (more like your older version with lots of swich/case/ifs) but it performs a lot faster (on the XBox).

its very hard to profile for the xbox. I am trying an old trick from the pocket PC development, where you can run NETCF code natively on the desktop...you have to disable all XNA rendering though, since the base assemblies on XBox and PC are different...but otherwise...that should work. Then use a Desktop profiler like EQUTEK or even the VS08 Profiler.

Let me see what else I find....

I am Looking forward to see your new version :)
Coordinator
Dec 20, 2008 at 7:29 PM

Hey Chris,

Good stuff.  I still have the GetType when determining which CollisionDetector to use. I'll switch that to use something similar to what you have suggested.  Other things I have done:

  •  Attempted to pool all dynamic objects.
  • Changed "object as type" to "(type)object" where I could.
  • Attempted to remove boxing operations.
  • Passed value types by reference where appropriate.
  • Inlined functions where appropriate.

I've been working on preparing the release every chance I get.  I just need to fix the examples to work with the changes I've made to some of the classes of the framework and test on hte XBox360.

Thanks for the suggestions.  Keep them coming!

Dec 25, 2008 at 12:33 AM
Excellent! These are great tuning areas!

Once I get your new framework I will run it against a couple profilers to see where else we can save some memory and performance (right now XBox gives me an out-of-memory exception).

One request, and I think you got this from another user already:

I want to have some static objects in my playfield, but I need to animate them, at least with rotation.
I have not tried this yet, but if I apply Torgue to an object that is static, will it spin or stay put?
Dec 26, 2008 at 2:03 AM
Found a slight problem with your multithreading

Seams like there are sometimes some synchronization problems between the main thread and the Physics thread.
I found if I add the following if statement around your "WaitOne()" call the thread and the physics component dispose correctly :)

(in your Update() routine of the PhyicsComponent class)

 

// Wait for the other thread's process to finish.

 

 

if (!this.disposing)

 

 

this.endEvent.WaitOne();

 

Coordinator
Dec 29, 2008 at 12:38 AM
Hi Chris, The multithreading issue should not be in the upcoming release.  That area of the framework does not exist as it was.  Keep you findings coming though!  It's very helpful to have another pair of eyes on code.

As far as your previous post, Are you requesting that you would be able to define a rigid body that integrates it's position/orientation and velocities, causes collisions BUT is not affect by collisions with other objects?  I could add another RigidBodyFlag that could define something like this.  Would that satisy your request?

It shouldn't be too much longer.  Once I solve the issue with composite shapes and add your request, I'll upload the code.
Dec 29, 2008 at 5:18 AM

Sweet!

I added this to your Integrate Method of RigidBody..that did do the trick for me to have static bodies at least rotate. Position changes would be super additionally:)

 

 

if ((this.Flags & (RigidBodyFlags.Disabled | RigidBodyFlags.Static)) != RigidBodyFlags.None)

 

{

 

 

Quaternion rotationQs = new Quaternion(this.Rotation * elapsed, 0.0f);

 

 

Quaternion.Multiply(ref rotationQs, ref this.Orientation, out rotationQs);

 

 

this.Orientation += rotationQs * 0.5f;

 

 

this.CalculateDerivedData();

 

 

return;

 

}

Dec 31, 2008 at 1:56 AM
Quick question: Do you have some experience values for your friction and restitution factors to simulate
Ice, Cloth, Sand, Wood, Metal and Bricks for your Planes/Objects?
Coordinator
Jan 2, 2009 at 1:17 AM
Unfortunately, no.  I've just tuned until it felt right.  Keep in mind the RigidBody.LinearDamping and RigidBody.AngularDamping as well when simulating certain materials.

I have a few questions for you when you get a moment:
- How many dynamic spheres/boxes are normally in play during gameplay?
- Are the spheres/boxes normally in a collision state or in the "air" not touching one another most of the time?
- Are you using the Joint class?

Thanks.
Jan 2, 2009 at 5:46 AM
I see..thanks on the Damping hints..

To your questions:

+ About 100-200 spheres per split screen...not too many boxes maybe 10
+ All spheres are always in a collision state
+ not using the joint class yet..I have not found out how ;) Can you explain how to use it?

Thanks
Coordinator
Jan 5, 2009 at 11:36 PM
100-200 spheres per split-screen?  On Windows, this might be a possibility but on the XBox that would be stretching it a bit with only one thread dedicated to physics.  I just tested on the XBox and I can get around 200 collision shapes running at an almost steady 60 fps with the first example I made.  Drawing actually slows it down since I'm not doing any type of instancing.

I bumped it up to 300 collision shapes and the frame rate dropped significantly.

I actually removed the joint class and added a constraint system...that will be in the release after next. :) I also removed the CollisionTerrain and will be adding it back as well.  I'm wrapping things up and should be uploading the source code this week.
Jan 5, 2009 at 11:56 PM
I did some testing with my code and I think I will get about 100 collisions shapes going per split screen in different spaces.
Once I get your new drop, I probably optimize it just for my game to squeeze out some more FPS.

Not using the collisionTerrain, yet, but would like to at some time. I dont need a heighmap but rather a playfield arena where the spheres bounce off walls and where the floow is somewhat uneven.

Good luck with the uploading...cannot wait to see it :)
Coordinator
Jan 11, 2009 at 6:07 PM
Okay. The new source code is up.  There are a few structure changes and compiler directives but overall works about the same as before.  The biggest change is I started using a Matrix for orientations instead of Quaternion.  I didn't want to create a transformation every simulation step from the position and orientation since alot of times it wasn't needed, but I still needed the rotation matrix. You can switch it back by adding the QUATERNION_ORIENTATION compiler directive to the project(s) but it isn't as optimized as the Matrix version.  I'm doing that right now.

I also added a container object for the association between a RigidBody and it's CollisionShapes, the CollisionGroup.  The main reason for this to not require integration checks for static objects and so the BroadPhase collision strategies had a better reference to the data it needed.  Collision resolution also benefits from this as well.

Lastly, there is no need to manually integrate the rigid bodies in a IPhysicsIntegrator.  It happens automatically in the PhysicsComponent.  So, does collision detection.  You can specify what CollisionSystem (broadphase strategy) by passing in an instance into the constructor.

Let me know if you have any questions.
Jan 12, 2009 at 1:28 AM
I integrated your new source with my game and it went fairly smooth! Congratulations.

I had to change a lot of my default values but once I played with them all looked good.

I did had to do one change to your code today since I am only using your physics parts.
With DEBUG enabled you dispay the surrounding boxes of your objects using your viewport class...that starts to include all sorts of interesting classes of yours:)
I changed your DEBUG directive to PHYDEBUG to make sure its still there.

GetService and AddService Funcion in your PhysicsComponent class. Since I am not using your GameService classes, I put those behind a preprocessor define.
Then everything compiled just fine.

I have one final remaining problem:

I am using 5 boxes to "restrain" my playfield ..including for the floor (It might be tilted and therefor I cannot just use a plane).
With your old version, the floor worked correctly but occasional the spheres went through the walls.
Now with your new versions, the spheres are "sinking" through my floor.

Do you have any suggestion what I can do to fix this? The balls should "rest" at some point in time on the floor...if the floor is tilted..they should rest in a corner of the playfield.
I played with all your parameters (Friction, Restitution, LinearDamping, Mass etc) but could not find any combination that kept the ball above the floor.

Any help would be excellent! As I said the rest looks perfect! Great job!
Coordinator
Jan 12, 2009 at 6:35 PM
Edited Jan 12, 2009 at 10:54 PM
There's a bug in the PhysicsComponent.Update method that might fix your issue.  It's a bug nonetheless.  These lines :

// Integrate the velocities and positions of active or recently activated rigid bodies.
rigidBody.IntegrateVelocity(elapsed);
rigidBody.AttemptDeactivation(elapsed);
rigidBody.IntegratePosition(elapsed);

should be:

// Integrate the velocities and positions of active or recently activated rigid bodies.
rigidBody.IntegrateVelocity(currentStepTime);
rigidBody.AttemptDeactivation(currentStepTime);
rigidBody.IntegratePosition(currentStepTime);

Also, if your moving your boxes with the RigidBody.Position property, use the RigidBody.UpdateTransform method instead.  Let me know if any of these help.

EDIT : Source code uploaded for the fix.
Jan 12, 2009 at 11:53 PM
Nope...the spheres still start spinning and then sink into the boxes.
With your last version I had to play with your "PenetrationCorrectionTolerance (0.01) and MaxPeneIteractions (256)" values to get it working.

I am using the QuadTreeCollisionSystem...is there maybe a different collision system I should try?
Jan 13, 2009 at 1:54 AM
Hmm...there is one more thing strange.
My spheres also go through planes...they slow down dramatically but they still sink even through planes....as if the collission is not correctly inverting the velocity if a sphere is colliding with the plane. Does that help you to pinpoint what I could do wrong?

I am using the non multithreaded version for now. I do have a collision callback but I do return true if I do not handle the collision.

I do not change the position or orientation after I created a new object.

How important is it to call the "CalculateMassProperties" function?
Jan 13, 2009 at 4:53 AM
I am getting closer to the problem I guess....for some reason my "acceleration" has to be set fairly hight (-300 on the Y axis) in order for my objects to fall down resonable fast.
Looking at the IntergrateVelocity method...this is causing the "down velocity" to always be > the tollerance for AutoDisabled. Even if the object "sits" on another one.
Well almost like in real life when the ground has a lower density then the object sitting on the ground...over time...the heavier object will "sink" into the ground. But looking at your code..these two objects (at that time) are not in relation to each other...the pure "Gravity" (Acceleration) is sinking my spheres.

If I remove my "acceleration" settings...my speheres never fall down as in your sample.....hmmm....gotta find out what is different here:)
Coordinator
Jan 13, 2009 at 5:32 AM
Hi Chris,

Depending on your scene the CollisionSystem chosen may matter.  The SweepAndPruneCollisionSystem has the most mileage as far as testing is concerned.

I forgot about the RigidBody.CalculateMassProperties method.  This was being called automatically when you added a CollisionShape to the RigidBody in previous releases.  You now have to call it manually...at least for now.  It should be called after all associations are established.  Example:

// Create sphere.
CollisionSphere sphere = new CollisionSphere();
sphere.Radius = 5.0f;
sphere.OffsetPosition = new Vector3(2.5, 0.0f, 0.0f)

// Create box.
CollisionBox box = new CollisionBox();
box.Extents = new Vector3(5.0f);
box.OffsetPosition = new Vector3(-2.5, 0.0f, 0.0f);

// Create rigid body.
RigidBody rigidBody = new RigidBody();

// Add shapes to rigid body.
rigidBody.CollisionGroup.CollisionShapes.Add(sphere);
rigidBody.CollisionGroup.CollisionShapes.Add(box);

// Calculate the mass and inertia tensor from the box and sphere.
rigidBody.CalculateMassProperties(1.0f);

// Add the rigid body to the physics service.
physics.RigidBodies.Add(rigidBody);

Your RigidBody.Acceleration seems a bit high.  I know -9.81 is really not the perfect value since I'm not really dealing with meters as my measurement.  You can make it larger but I don't think -300 will be very good for the descrete collision detection scheme I'm using.

What have you set the radius of your spheres to?  Large objects make take away from some precision.  Also, check your RigidBody.LinearDamping value.  Make sure it's small.  valid values are between 0.0f and 1.0f.  Make it 0.001f and see what happens.

How do the examples in the Oops.Xna.Framework.Testing.App project perform?  Are you seeing issues there?


Jan 13, 2009 at 5:54 AM
What does the "OffsetPosition" do? I have not used that yet.

Once I put the Acelleration down it seams to work fine now...at least with the plane...something still wrong with my floorplate "box"

The App project performs nicely...have not seen any issues there
Jan 13, 2009 at 7:10 AM
Well...it looks like the faster I put the physics.speed or the Acceleration (Gravity) the more likely the spheres are sinking in the ground

If I stay with the 9.81 and game speed 1 they do not sink...but thats way too slow. I guess I also have to play with the LinearMotionTheshold

My spheres have a radius of 16
My floor (one box) can be up to 300x5x300 (5 is the height)

I Box with 100x100x100 works just fine (that did not work with your old version ;))

So I guess its a sensitive working with the parameters to figure out what works and what not.
Maybe one suggestion for your next drop: Make the Thresholds and Acceleration depending on the physics speed. With a too high acelleration, the Threshold is never letting an object rest.
Another possibility would be to take the mass of the object and factor that somehow in the LinearMotionThreshold...like a real density factor...that you could even simulate Swamps :)
Jan 13, 2009 at 7:20 AM
ok...one last observation....the more a sphere is spinning the faster its sinken...it it does not spin and gets to "rest" that way...it does not sink...does that give you a hint?
Coordinator
Jan 14, 2009 at 12:54 AM
The CollisionShape.OffsetPosition/OffsetOrientation are for composite shapes.  Its the relative distance and orientation from the "center of mass"...sort of.

Well, I changed example 1 in the new source to create a box with extents of (300, 5, 300) instead of a plane and made 250 spheres of size 16 and dropped them on the box.  I also bumped up the gravity to 20.  It seemed to perform like expected.

Possibly, are you moving your boxes (i.e., floor and walls) by just updating the RigidBody.Position and RigidBody.Orientation directly or using the RigidBody.UpdateTransform method and that's when you see the spheres sinking into the boxes?  If this is the case, you might try applying a force or impulse to the boxes to move them into position instead.  Spheres won't react to a box that doesn't have velocity.  This would be the case with manually changing the transform of the box.  When a collision is resolved, there would be very little relative velocity so it wouldn't resolve the sphere colliding with a box very quickly.

Same thing with your spheres.  Apply forces or impulses to your spheres instead of manually changing the position and orientation of them.

Let me know.

Jan 14, 2009 at 1:38 AM
Thanks on the explanation for the OffsetPosition..I will use that later ;)

I dont have problems with boxes dropping on my box floor. Only with the spheres.

I dont move my objects wth Position and Orientation manually, only when I create them in the first place. Everything else is left to the physics.
That includes the walls, floor and spheres. When I create and add them to the Physics.Rigidbodies collection is the last time I use Position, Orientation and UpdateTransform for the last time.

If I bring in a new sphere by "shooting" it into the field..I use ApplyForceImpulse.

If I set the Physics.Speed=1 or 2 it seams to behave ok even with Gravity (Acceleration) set to a higher number...but as soon as I speed up my game (and I need at least 5 if not higher for the game to become "fun-fast" enough) the sphereses start to spin and sink. That does not happen with the plane...just with a box as the floor.

With your old version, I had to experiment with the PenetrationIteration and Tollerance until that did not happen. With the wrong values, the spheres started to sink in...then jump up again...sink in again.

Looking at your code it looks like the Velocity with the Acelleration always exceed the Treshhold and the sphere never gets to rest.

One statement of your above makes me wonder if its the cause of everything: "Spheres wont react to a box that doesnt have velocity" my boxes are static objects never have any velocity, (they are non moving floor and my walls)....so is that the reason? If I use the plane instead...is it possible to "tilt" the plane? That would be completely sufficient for my purposes.
Coordinator
Jan 14, 2009 at 2:15 AM

You're okay with the box(es) being static.  If you were manually moving your boxes during gameplay no velocity change would occur which would make collision response...er, unresponsive.  That's not the problem I'm sure.

I'm thinking it might be the size of the simulation steps and discrete collision detection.  By default, a simulation step is 1/60th of a second.  Meaning, it will integrate all rigid bodies with an elapsed time of 1/60th of second or less and catch up if a frame happens to be longer.  So two or more simulation steps could occur for one "update/frame" of a game.  Having your shapes moving quickly (large velocities or forces) means they will move further each simulation step, possibly moving shapes into "deep" collisions.

You can make the PhysicsComponent.TargetStepTime smallerto see if that helps.  1f/120f or 1f/180f maybe.  See if that helps.  This will of course make things slower but it would help to identify the problem.  Increasing the PhysicsComponent.CollisionIterationCount may help as well but it has the saem side effects.  Slower performance.

Let me know! 

Jan 14, 2009 at 2:26 AM
I tried both with no effect.

When a sphere rolls along the box...it starts spinning faster and faster and then sinks.
Spheres that drop vertically on a box with no rotation applied during creation, bounce until they sit...they never spin (as it should be) and never sink.
But as soon as I ApplyForceImpulse with a Velocity that is in an angle to the floor box, it bounces, starts to spin (correctly) and then at some point rolls along the box...while its rolling it starts spinning more (even more than it should) and it looks like its "digging" itself into the ground (box).

The AngularDamping...does it control the spinning?
My spehres, (although having the same size) have different masses (like plastic vs. bowling ball - same size but different mass). To set this different mass, I am using your CalculateMassProperty on the Rigidbody of the Sphere (i.e. from 0.7 to 10.0). I did not see a difference between the lighter spheres and the more heavier spheres at all yet. Did I not use this correctly?
Jan 14, 2009 at 2:48 AM
ok...I have a way for you to see the effect in your own sample:

Go to your ExampleScreen.cs and add in your Reset() function:

physics.Speed=15;

and in the sphere loop under CalculateMassProperties(1.0f);

rigidBody.Velocity = random.NextVector3(-0.1f, 0.1f);

Than start your Sample screen with Example 1

You will see that the spheres and boxes that still "spin" sink into the ground...while those spheres and boxes that do not spin, remain where they are when the spinning has stopped.

I had it happen also with Speed=3...looks like the Speed factor is not doing the same thing it did with your old version...no linear, can that be?
Coordinator
Jan 14, 2009 at 2:52 AM

Try adding a little bit of AngularDamping.  It should keep your rotation in check since rotation will accummulate every timestep from torque and collision impulses.  I think we're getting closer to the issue.

Just in case, make sure CalculateMassProperties after the sphere is added to the rigid body.

Coordinator
Jan 15, 2009 at 3:01 AM
From applying your modifications to the example screen, I can see what you have described.  Yikes.  The issue is this line in Collision.PreStep:

// Limit the desired velocity change in the direction of the collision normal.

 

point.desiredVelocityChange = MathHelper.Clamp(point.desiredVelocityChange, 0.0f, 0.5f);

As you can see, it's limiting the "desired velocity change" of a collision point to 0.5f, or the magnitude of the velocity along the normal required to move the collision point out of contact.  It helps with stability to keep this scalar managable.  You can, of course, make it bigger.  It'll help with your issue...at a cost of course.  1.5f - 2.5f fixes the issue but just introduces others as you'll see.

I checked in another source code update.  There are some fixes but I added an example for a box of balls (example 2).  Might help, I don't know.  I'll probably expose the "desired velocity change" range for the next source code update and see if there is a better scheme available to prevent the stutter when making the value too high.

I you'd like you can contact me through codeplex PM - http://www.codeplex.com/site/users/view/fretboardoffury.

Jan 15, 2009 at 4:15 AM
Excellent!!! That did the trick...and I have not seen any side effects so far. I used 2.5 and it worked just fine with a physics speed of 10 even at speed 15
Jan 15, 2009 at 4:55 AM
found another minor issue:

In your "DetectCollisions" Method of the "CollisionSystems" class you did not exclude the "NoResponse" objects from collision detection:

    if ((rigidBodies[i].Flags & (RigidBodyFlags.Disabled | RigidBodyFlags.Static | RigidBodyFlags.NoResponse)) != RigidBodyFlags.None)

I do use a huge array of "ghost" spheres to simulate an explosion...I want to have these spheres follow the physics movement...but dont care about the collisions at all.
I found, if I just probe in the OnCollided Callback if one of those spheres collides with anything..it still slows down the system significantly because it runs through all your collision detection code.

Once I added the NoResponse exclude in your line above, the game runs lightning fast! And I can use the spheres as a mini fireworks particle system ;)
Coordinator
Jan 15, 2009 at 6:35 PM
I was making the NoResponse mean that it doesn't respond to collisions but it still causes collisions with other objects.  Sort of a static object that still is affected by forces (gravity) and is integrated.

You can accomplish the same thing by setting the CollisionGroup.CategoryFlags or CollisionShape.CategoryFlags to zero.  CollisionGroup.CategoryFlags would be better.