Page 1 of 1

Unit Measures [and other things :)]

Posted: Fri Jul 01, 2011 8:34 am
by -=Magic=-
I read that Bepu is unitless, but for consistency I need a hint :)

I'm developing a pool game, using real dimensions. So, I used 1 unit as 1cm. A Pool table is 254cm x 127cm, so I have a surface of 254unit x 127 unit. A ball has a diameter of 5.715cm, so I have a sphere with diameter equal to 5.715 units.

Now, the gravity is -9.81m/s2. With the settings above, I have

Space.ForceUpdater.Gravity = new Vector3(0, -981, 0f); // 9.81m/s2 = 981cm/s2

but if I use this value, the spheres does little bouncing over the table, even if they aren't moving. (if I set gravity to 9.81 or 98.1, the spheres doesn't bounce).

Every sphere has a mass of 0.2f (each pool ball has a weight of about 200gr).

how may I solve the bouncing sphere effect?

Surface Table Bounciness = 0;
Sphere Bounciness = 0.8f;

BouncinessBlendMethod = PropertyBlendMethod.Average;

Re: Unit Measures

Posted: Fri Jul 01, 2011 9:35 am
by -=Magic=-
Ok, now I solved :) (I set BouncinessBlendMethod = PropertyBlendMethod.Min, so that with TableBounciness = 0, this stop the sphere to bounce)

but, now I've another poblem. when the sphere collide with the external cushion around the table, the sphere tends to stick near to it. expecially at lower speed, even if the collision is perpendicular to the cushion. (the sphere hit the cushion, bounce, but after few roll back to the cushion)

TableStaticFriction = 1f;
TableKineticFriction = 0.4f;
TableBounciness = 0f;
CushionStaticFriction = 1f;
CushionKineticFriction = 0.2f;
CushionBounciness = 0.8f;
BallStaticFriction = 0.2f;
BallKineticFriction = 0.2f;
BallBounciness = 0.8f;
BallLinearDamping = 0.1f;
AngularDamping = 0.3f;
BallMass = 0.2f;

BouncinessBlendMethod = PropertyBlendMethod.Min;

Table and Cushion have no mass, so they are kinematic entities.


---- Edit:

Ok, the problem seems t be that when tha ball hit the cushion, then it takes too much angular velocity. I may remove this? so that the collision with the cushion doesn't add any rolling effect to the ball?

Re: Unit Measures [and other things :)]

Posted: Fri Jul 01, 2011 1:19 pm
by -=Magic=-
I noticed some sort of undeterministic behaviours.

I'm on the table. There's only one ball. I'm just behind the ball, and I see the ball perpedicular to the opposite table cushion.

I press a key, and this command execute:

Code: Select all

Vector3 direction = game.Camera.WorldMatrix.Forward;
direction.Y = 0;
sphere.ApplyImpulse(sphere.Position, direction * MaxImpulse);
but, if I repeat this command I get different results. (the ball doesn't stop at the same point, for example).
if I exec the command but with a different angle, the problem is more visible, as the ball get some strange effects every time collide with the perimetral cushion.

In a pool game, it's important to have deterministic and repeatable simulation.

any idea?

Re: Unit Measures [and other things :)]

Posted: Fri Jul 01, 2011 2:17 pm
by -=Magic=-
I've done some experiments.
Pos: position of the sphere
Vel: Linear Velocity
Ang: Angular Velocity

FixedTimeStep = false; First Try: 1102 Update from start to end
Start Impulse to Entity: MasterOfPool.Ball - Impulse: {X:250 Y:0 Z:0} - Pos: {X:-71 Y:12,86 Z:0} - Vel: {X:0 Y:0 Z:0} - Ang: {X:0 Y:0 Z:0}
Entity: MasterOfPool.Ball - Delta: 0,0166015 - Pos: {X:-50,33923 Y:12,86 Z:0} - Vel: {X:1239,646 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-2,853371}
Entity: MasterOfPool.Ball - Delta: 0,0170007 - Pos: {X:-29,85071 Y:12,86 Z:0} - Vel: {X:1229,311 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-5,689833}
Entity: MasterOfPool.Ball - Delta: 0,0309053 - Pos: {X:-9,534159 Y:12,86 Z:0} - Vel: {X:1218,993 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-8,509485}
Entity: MasterOfPool.Ball - Delta: 0,002232 - Pos: {X:10,61075 Y:12,85999 Z:0} - Vel: {X:1208,694 Y:-0,000402584 Z:0} - Ang: {X:0 Y:0 Z:-11,31235}
Entity: MasterOfPool.Ball - Delta: 0,0163161 - Pos: {X:30,5843 Y:12,85999 Z:0} - Vel: {X:1198,413 Y:-0,0004002104 Z:0} - Ang: {X:0 Y:0 Z:-14,09868}
Entity: MasterOfPool.Ball - Delta: 0,0167851 - Pos: {X:50,38679 Y:12,85999 Z:0} - Vel: {X:1188,15 Y:2,030042E-08 Z:0} - Ang: {X:0 Y:0 Z:-16,86855}
Entity: MasterOfPool.Ball - Delta: 0,0169515 - Pos: {X:70,01853 Y:12,85999 Z:0} - Vel: {X:1177,904 Y:2,069959E-08 Z:0} - Ang: {X:0 Y:0 Z:-19,62194}
Entity: MasterOfPool.Ball - Delta: 0,0308686 - Pos: {X:89,47982 Y:12,85999 Z:0} - Vel: {X:1167,677 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-22,35901}
Entity: MasterOfPool.Ball - Delta: 0,008089 - Pos: {X:108,771 Y:12,85999 Z:0} - Vel: {X:1157,468 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-25,07986}
Entity: MasterOfPool.Ball - Delta: 0,0108067 - Pos: {X:124,657 Y:12,85999 Z:0} - Vel: {X:1147,276 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-27,78459}
:
:
Entity: MasterOfPool.Ball - Delta: 0,0328407 - Pos: {X:-10,66328 Y:12,85 Z:0,002626768} - Vel: {X:0 Y:0 Z:0} - Ang: {X:-8,449786E-12 Y:1,260333E-12 Z:-1,904943E-06}



FixedTimeStep = false; Second Try: 1080 Update from start to end
Start Impulse to Entity: MasterOfPool.Ball - Impulse: {X:250 Y:0 Z:0} - Pos: {X:-71 Y:12,86 Z:0} - Vel: {X:0 Y:0 Z:0} - Ang: {X:0 Y:0 Z:0}
Entity: MasterOfPool.Ball - Delta: 0,0165417 - Pos: {X:-50,33923 Y:12,86 Z:0} - Vel: {X:1239,646 Y:0 Z:0} - Ang: {X:6,844755E-12 Y:2,881559E-12 Z:-2,853371}
Entity: MasterOfPool.Ball - Delta: 0,0167141 - Pos: {X:-29,85071 Y:12,86 Z:1,750991E-15} - Vel: {X:1229,311 Y:0 Z:1,050594E-13} - Ang: {X:1,106385E-11 Y:-3,424302E-12 Z:-5,689833}
Entity: MasterOfPool.Ball - Delta: 0,0167312 - Pos: {X:-9,534159 Y:12,86 Z:7,554673E-15} - Vel: {X:1218,993 Y:0 Z:3,48221E-13} - Ang: {X:1,898416E-11 Y:-5,548519E-12 Z:-8,509485}
Entity: MasterOfPool.Ball - Delta: 0,0165844 - Pos: {X:10,61075 Y:12,85999 Z:1,430272E-14} - Vel: {X:1208,694 Y:-0,000402584 Z:4,048825E-13} - Ang: {X:4,09723E-12 Y:-3,709922E-12 Z:-11,31235}
Entity: MasterOfPool.Ball - Delta: 0,0166738 - Pos: {X:30,5843 Y:12,85999 Z:1,857182E-14} - Vel: {X:1198,413 Y:-0,0004002104 Z:2,56146E-13} - Ang: {X:-9,073994E-12 Y:9,187734E-13 Z:-14,09868}
Entity: MasterOfPool.Ball - Delta: 0,0166069 - Pos: {X:50,38679 Y:12,85999 Z:3,723246E-14} - Vel: {X:1188,15 Y:2,030042E-08 Z:1,119639E-12} - Ang: {X:5,133543E-11 Y:-1,267754E-11 Z:-16,86855}
Entity: MasterOfPool.Ball - Delta: 0,0166661 - Pos: {X:70,01853 Y:12,85999 Z:6,555276E-14} - Vel: {X:1177,904 Y:2,069959E-08 Z:1,699218E-12} - Ang: {X:3,350334E-11 Y:1,751004E-11 Z:-19,62194}
Entity: MasterOfPool.Ball - Delta: 0,0167709 - Pos: {X:89,47982 Y:12,85999 Z:9,600896E-14} - Vel: {X:1167,677 Y:0 Z:1,827372E-12} - Ang: {X:7,933651E-12 Y:1,970664E-11 Z:-22,35901}
Entity: MasterOfPool.Ball - Delta: 0,0166359 - Pos: {X:108,771 Y:12,85999 Z:1,27924E-13} - Vel: {X:1157,468 Y:0 Z:1,914902E-12} - Ang: {X:5,603239E-12 Y:-9,391217E-12 Z:-25,07986}
:
:
Entity: MasterOfPool.Ball - Delta: 0,0166963 - Pos: {X:2,277892 Y:12,85998 Z:0,006737435} - Vel: {X:0 Y:0 Z:0} - Ang: {X:-7,659232E-12 Y:7,591094E-12 Z:-4,729362E-07}



FixedTimeStep = true; First Try: 1121 Update from start to end
Start Impulse to Entity: MasterOfPool.Ball - Impulse: {X:250 Y:0 Z:0} - Pos: {X:-71 Y:12,86 Z:0} - Vel: {X:0 Y:0 Z:0} - Ang: {X:0 Y:0 Z:0}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-50,33923 Y:12,86 Z:0} - Vel: {X:1239,646 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-2,853371}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-29,85071 Y:12,86 Z:0} - Vel: {X:1229,311 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-5,689833}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-9,534159 Y:12,86 Z:0} - Vel: {X:1218,993 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-8,509485}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:10,61075 Y:12,85999 Z:0} - Vel: {X:1208,694 Y:-0,000402584 Z:0} - Ang: {X:0 Y:0 Z:-11,31235}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:30,5843 Y:12,85999 Z:0} - Vel: {X:1198,413 Y:-0,0004002104 Z:0} - Ang: {X:0 Y:0 Z:-14,09868}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:50,38679 Y:12,85999 Z:0} - Vel: {X:1188,15 Y:2,030042E-08 Z:0} - Ang: {X:0 Y:0 Z:-16,86855}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:70,01853 Y:12,85999 Z:0} - Vel: {X:1177,904 Y:2,069959E-08 Z:0} - Ang: {X:0 Y:0 Z:-19,62194}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:89,47982 Y:12,85999 Z:0} - Vel: {X:1167,677 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-22,35901}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:108,771 Y:12,85999 Z:0} - Vel: {X:1157,468 Y:0 Z:0} - Ang: {X:0 Y:0 Z:-25,07986}
:
:
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-13,85999 Y:12,85998 Z:0,003719465} - Vel: {X:0 Y:0 Z:0} - Ang: {X:-1,256907E-11 Y:-1,553706E-11 Z:-1,891747E-06}



FixedTimeStep = true; Second Try: 1151 Update from start to end
Start Impulse to Entity: MasterOfPool.Ball - Impulse: {X:250 Y:0 Z:0} - Pos: {X:-71 Y:12,86 Z:4,643032E-25} - Vel: {X:1,604723E-23 Y:2,121149E-28 Z:-4,293519E-28} - Ang: {X:0 Y:0 Z:0}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-50,33923 Y:12,86 Z:4,642961E-25} - Vel: {X:1239,646 Y:0 Z:-4,257956E-28} - Ang: {X:-2,720671E-11 Y:5,161751E-12 Z:-2,853371}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-29,85071 Y:12,86 Z:-5,872835E-15} - Vel: {X:1229,311 Y:0 Z:-3,523701E-13} - Ang: {X:-3,710825E-11 Y:8,925829E-12 Z:-5,689833}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-9,534159 Y:12,86 Z:-3,21876E-14} - Vel: {X:1218,993 Y:0 Z:-1,578886E-12} - Ang: {X:-9,560829E-11 Y:2,231561E-11 Z:-8,509485}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:10,61075 Y:12,85999 Z:-8,115328E-14} - Vel: {X:1208,694 Y:-0,000402584 Z:-2,93794E-12} - Ang: {X:-9,351139E-11 Y:2,855701E-11 Z:-11,31235}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:30,5843 Y:12,85999 Z:-1,604851E-13} - Vel: {X:1198,413 Y:-0,0004002104 Z:-4,759907E-12} - Ang: {X:-1,161721E-10 Y:1,403995E-11 Z:-14,09868}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:50,38679 Y:12,85999 Z:-2,818221E-13} - Vel: {X:1188,15 Y:2,030042E-08 Z:-7,280225E-12} - Ang: {X:-1,522213E-10 Y:1,251375E-10 Z:-16,86855}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:70,01853 Y:12,85999 Z:-4,170162E-13} - Vel: {X:1177,904 Y:2,069959E-08 Z:-8,111646E-12} - Ang: {X:-5,127702E-11 Y:-1,111607E-11 Z:-19,62194}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:89,47982 Y:12,85999 Z:-5,568073E-13} - Vel: {X:1167,677 Y:0 Z:-8,387464E-12} - Ang: {X:-1,950852E-11 Y:-8,875821E-12 Z:-22,35901}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:108,771 Y:12,85999 Z:-7,243375E-13} - Vel: {X:1157,468 Y:0 Z:-1,005181E-11} - Ang: {X:-9,254746E-11 Y:2,875119E-11 Z:-25,07986}
:
:
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-22,61569 Y:12,85957 Z:0,01891729} - Vel: {X:0 Y:0 Z:0} - Ang: {X:-4,184632E-15 Y:6,582845E-12 Z:6,711678E-19}



FixedTimeStep = true; Third Try: 1078 Update from start to end
Start Impulse to Entity: MasterOfPool.Ball - Impulse: {X:250 Y:0 Z:0} - Pos: {X:-71 Y:12,86 Z:0} - Vel: {X:0 Y:0 Z:0} - Ang: {X:0 Y:0 Z:0}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-50,33923 Y:12,86 Z:0} - Vel: {X:1239,646 Y:0 Z:0} - Ang: {X:4,429294E-11 Y:2,178133E-10 Z:-2,853371}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-29,85071 Y:12,86 Z:1,719512E-14} - Vel: {X:1229,311 Y:0 Z:1,031707E-12} - Ang: {X:1,086495E-10 Y:2,814818E-10 Z:-5,689833}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:-9,534159 Y:12,86 Z:7,633235E-14} - Vel: {X:1218,993 Y:0 Z:3,548234E-12} - Ang: {X:1,964244E-10 Y:2,041403E-10 Z:-8,509484}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:10,61075 Y:12,85999 Z:2,166477E-13} - Vel: {X:1208,694 Y:-0,000402584 Z:8,418919E-12} - Ang: {X:3,336495E-10 Y:2,906386E-10 Z:-11,31235}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:30,5843 Y:12,85999 Z:4,499539E-13} - Vel: {X:1198,413 Y:-0,0004002104 Z:1,399837E-11} - Ang: {X:3,553896E-10 Y:-1,350069E-11 Z:-14,09867}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:50,38679 Y:12,85999 Z:8,136136E-13} - Vel: {X:1188,15 Y:2,030042E-08 Z:2,181958E-11} - Ang: {X:4,719236E-10 Y:-3,563472E-10 Z:-16,86855}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:70,01853 Y:12,85999 Z:1,470803E-12} - Vel: {X:1177,904 Y:2,069959E-08 Z:3,943137E-11} - Ang: {X:1,011155E-09 Y:2,540629E-10 Z:-19,62194}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:89,47982 Y:12,85999 Z:2,343892E-12} - Vel: {X:1167,677 Y:0 Z:5,238534E-11} - Ang: {X:7,296185E-10 Y:1,558534E-10 Z:-22,35901}
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:108,771 Y:12,85999 Z:3,390797E-12} - Vel: {X:1157,468 Y:0 Z:6,281428E-11} - Ang: {X:5,798322E-10 Y:-6,87304E-10 Z:-25,07986}
:
:
Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:2,294361 Y:12,85998 Z:-0,0003665402} - Vel: {X:0 Y:0 Z:0} - Ang: {X:9,917894E-13 Y:9,373031E-12 Z:-4,729362E-07}



The first thing to notice, is that I gave an Impulse over the X axis, but on the second try of both session (without and with FixedTimeStep) the Z value of LinearVelocity is changed. Why?

And in every try, at step 4,5,6,7 the Y value change, into negative value too. why?

Maybe a kind of "threshold limit value" should be inserted so that a value unde this, should be considered equal to 0.

Consider the second try:

Start Impulse to Entity: MasterOfPool.Ball - Impulse: {X:250 Y:0 Z:0} - Pos: {X:-71 Y:12,86 Z:0} - Vel: {X:0 Y:0 Z:0} - Ang: {X:0 Y:0 Z:0}
Entity: MasterOfPool.Ball - Delta: 0,0165417 - Pos: {X:-50,33923 Y:12,86 Z:0} - Vel: {X:1239,646 Y:0 Z:0} - Ang: {X:6,844755E-12 Y:2,881559E-12 Z:-2,853371}
Entity: MasterOfPool.Ball - Delta: 0,0167141 - Pos: {X:-29,85071 Y:12,86 Z:1,750991E-15} - Vel: {X:1229,311 Y:0 Z:1,050594E-13} - Ang: {X:1,106385E-11 Y:-3,424302E-12 Z:-5,689833}
Entity: MasterOfPool.Ball - Delta: 0,0167312 - Pos: {X:-9,534159 Y:12,86 Z:7,554673E-15} - Vel: {X:1218,993 Y:0 Z:3,48221E-13} - Ang: {X:1,898416E-11 Y:-5,548519E-12 Z:-8,509485}
Entity: MasterOfPool.Ball - Delta: 0,0165844 - Pos: {X:10,61075 Y:12,85999 Z:1,430272E-14} - Vel: {X:1208,694 Y:-0,000402584 Z:4,048825E-13} - Ang: {X:4,09723E-12 Y:-3,709922E-12 Z:-11,31235}
Entity: MasterOfPool.Ball - Delta: 0,0166738 - Pos: {X:30,5843 Y:12,85999 Z:1,857182E-14} - Vel: {X:1198,413 Y:-0,0004002104 Z:2,56146E-13} - Ang: {X:-9,073994E-12 Y:9,187734E-13 Z:-14,09868}
Entity: MasterOfPool.Ball - Delta: 0,0166069 - Pos: {X:50,38679 Y:12,85999 Z:3,723246E-14} - Vel: {X:1188,15 Y:2,030042E-08 Z:1,119639E-12} - Ang: {X:5,133543E-11 Y:-1,267754E-11 Z:-16,86855}
Entity: MasterOfPool.Ball - Delta: 0,0166661 - Pos: {X:70,01853 Y:12,85999 Z:6,555276E-14} - Vel: {X:1177,904 Y:2,069959E-08 Z:1,699218E-12} - Ang: {X:3,350334E-11 Y:1,751004E-11 Z:-19,62194}

Third line: Vel: {X:1229,311 Y:0 Z:1,050594E-13}
a value of 1,050594E-13 should be considered equal to 0. can be taken as real value. we are simulating the physic. but with approximations due to the hardware limits.

Using a global const value like 1E-8 as limit threashold should be fix the undeterministic behaviour (if there isn't any other element which cause undeterminism).
If someone need more precision, could include the source code, modify the const value, and recompile the physic engine.

Re: Unit Measures [and other things :)]

Posted: Fri Jul 01, 2011 5:07 pm
by Norbo
I'm developing a pool game, using real dimensions. So, I used 1 unit as 1cm. A Pool table is 254cm x 127cm, so I have a surface of 254unit x 127 unit. A ball has a diameter of 5.715cm, so I have a sphere with diameter equal to 5.715 units.
That pool table size is bigger than I would usually recommend. Sticking to a 0.5 to 10 units range for object dimensions is a good idea, though the simulation will usually work fine outside of that soft range. If you're using only objects which have special cases with each other, like sphere-sphere, sphere-box, and sphere-triangle, sizes are much less of an issue. Other pairs that use the general convex-convex test directly or indirectly may sometimes have problems.
Space.ForceUpdater.Gravity = new Vector3(0, -981, 0f); // 9.81m/s2 = 981cm/s2

but if I use this value, the spheres does little bouncing over the table, even if they aren't moving. (if I set gravity to 9.81 or 98.1, the spheres doesn't bounce).
Relative to the time step, object sizes, and engine tuning, that gravity is immense. The bouncing in particular can be either solved by removing bounciness, like you did, or by tuning the CollisionResponseSettings.BouncinessVelocityThreshold. Increasing it by a factor of 10 or 100, like your gravity, would likely do the job.

If you can afford the extra simulation time, decreasing the Space.TimeStepSettings.TimeStepDuration from 1/60f to something like 1/120f or 1/180f would help too. Pool is not exactly complicated, so this should simulate pretty quickly even on the Xbox360/WP7. You'll also want to pass in the elapsed time to the space.Update method so it updates the proper number of times.
Ok, the problem seems t be that when tha ball hit the cushion, then it takes too much angular velocity. I may remove this? so that the collision with the cushion doesn't add any rolling effect to the ball?
Yes, but it won't be physically correct. To eliminate all rotation, set the ball's LocalInertiaTensorInverse = new Matrix3X3(). Friction will need to be retuned since the balls are not rolling, but sliding.

Selectively ignoring rotation only on cushion impact is trickier and I wouldn't recommend going down that road. Retuning properties or geometry to give a more desired result would be a better idea than trying to sometimes fake rotation and sometimes not. Decreasing the time step duration will also make the simulation more accurate.
but, if I repeat this command I get different results. (the ball doesn't stop at the same point, for example).
if I exec the command but with a different angle, the problem is more visible, as the ball get some strange effects every time collide with the perimetral cushion.
If you have multithreading on, the engine is not deterministic by design. You can disable multithreading on a per-component basis if you'd like, using the AllowMultithreadingProperty. The three phases which must be single threaded to support determinism are the Space.NarrowPhase, Space.Solver, and Space.BroadPhase.

You may find that, because your simulation is so tiny, multithreading does not help at all (or even adds a little overhead). The time it takes to feed the threads for each stage is probably as long as just doing the whole stage when dealing with ~10 objects. If you'd like to turn off multithreading entirely, do not give any threads to the space's ThreadManager. More information about internal multithreading can be found here: http://bepuphysics.codeplex.com/wikipag ... umentation

If multithreading isn't on, then the nondeterminism is coming from some other source, like the initial configuration.
In a pool game, it's important to have deterministic and repeatable simulation.
If at all possible, it's a good idea to avoid the requirement of determinism. It's hard enough to guarantee on a local machine, let alone on remote machines that may be a different platform entirely (primarily an issue in desktop games). If you need determinism for replays or networked play, consider implementing recording and playback explicitly using compressed, keyframed animation.

A single player trying to do something similar twice will have so many changed variables in the simulation that it would be silly for them to assume it will do exactly the same thing. It will do something similar enough, unless there are bugs that are introducing significant errors- but that needs to be fixed directly and isn't really related to determinism.
The first thing to notice, is that I gave an Impulse over the X axis, but on the second try of both session (without and with FixedTimeStep) the Z value of LinearVelocity is changed. Why?

And in every try, at step 4,5,6,7 the Y value change, into negative value too. why?
The Z value is extremely tiny and effectively 0. The Y value is extremely close to the original value. Floating point math isn't perfect; some collision normal might have pointed a few billionths of a degree off of straight up and introduced an invisible Z axis movement. Maybe the ball fell imperceptibly as it passed between two triangles. This will not affect determinism on a local machine, and the values involved are far, far smaller than the deviations that occur within a real-life pool game.

Note that FixedTimeStep does not change the physics simulation. If you're passing the elapsed time into the Space.Update, the Space.Update updates with a fixed timestep (Space.TimeStepSettings.TimeStepDuration) as many times as necessary to get as close to the current accumulated time as possible. This will throw off any determinism testing as well if the updates aren't counted properly, because the simulation could do an arbitrary number of updates in a single Game.Update while internal time stepping is being used.
Maybe a kind of "threshold limit value" should be inserted so that a value unde this, should be considered equal to 0. Third line: Vel: {X:1229,311 Y:0 Z:1,050594E-13}
a value of 1,050594E-13 should be considered equal to 0. can be taken as real value. we are simulating the physic. but with approximations due to the hardware limits.

Using a global const value like 1E-8 as limit threashold should be fix the undeterministic behaviour (if there isn't any other element which cause undeterminism).
These values are not causing nondeterminism, and clamping them out would not stop nondeterminism. If the simulation is set up properly and has truly identical starting configurations, it will be deterministic, at least locally. Guaranteeing everything necessary (inside and outside of the physics) is a pain and I would strongly recommend just going with a replay system or some other approach if at all possible.

Re: Unit Measures [and other things :)]

Posted: Fri Jul 01, 2011 9:57 pm
by -=Magic=-
I need determinism not for replay, but for the AI. The AI should calculate which kind of shoot is better.. but if there is undeterminism, then when the CPU perform the shoot choiced, the result isn't what expected.

I'll try to disable multithreading.

for dimensions, the table size is 254 x 127 cm = 254 x 127 untis, but the bigger Entity is the cushion on the wider part of the table, and their size is about 110cmx5cm = 110 x 5 unit.
Now, I may consider to scale down of a factor of 10, so I get a ball of 0.5 unit and a cushion of 11 unit.


The experiment that I did was done throwing a ball right a perpendicular obstacle. I don't think that I got 5 different results only because I throw a 5units entity versus a 60units box.
and I stay with the idea that a threshod limit valuse should be used :)

BTW, I'll check your suggestions, and I'll write what's appends :)

Re: Unit Measures [and other things :)]

Posted: Sat Jul 02, 2011 10:55 pm
by -=Magic=-
Space.NarrowPhase.AllowMultithreading = false;
Space.Solver.AllowMultithreading = false;
Space.BroadPhase.AllowMultithreading = false;

Fixed the problem. :)
there are errors on the final position, but with a delta of 10-3. (with a threshold limit value, these errors can be removed too :) )

Here the final print of three test:
1. Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:2,28676 Y:12,85998 Z:0,003710312} - Vel: {X:0 Y:0 Z:0} - Ang: {X:-3,696448E-12 Y:-2,049909E-11 Z:-4,729362E-07}
2. Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:2,288896 Y:12,85998 Z:0,006780657} - Vel: {X:0 Y:0 Z:0} - Ang: {X:-7,593142E-12 Y:-4,505428E-12 Z:-4,729362E-07}
3. Entity: MasterOfPool.Ball - Delta: 0,0166667 - Pos: {X:2,284799 Y:12,85998 Z:0,005732001} - Vel: {X:0 Y:0 Z:0} - Ang: {X:-6,629984E-12 Y:7,637165E-12 Z:-4,729362E-07}

Re: Unit Measures [and other things :)]

Posted: Sat Jul 02, 2011 11:15 pm
by Norbo
It will indeed most likely be close enough, but those simulations still might not be deterministic. Clamping to zero won't help for the numbers well above zero and there's no reason why any number is more 'correct' than another. In fact, clamping could magnify any existing nondeterminism because it introduces discontinuities.

The final differences probably come from some tiny unhandled part of the simulation, like un-reset solver permutation indexing, or from external factors like stopping the test at a different update count.

But so long as the simulation is 'close enough,' the AI will be able to make fine guesses as to what it should do. If the simulation is still nondeterministic due to some tiny thing somewhere, and you do find yourself needing perfect reproduction later, I would again recommend the replay approach. For example, record the AI's own simulations and play back the one it chooses. It would be easier for you than going through the effort of finding every little thing that might be introducing nondeterminism.

Re: Unit Measures [and other things :)]

Posted: Mon Nov 21, 2011 2:21 pm
by snooker
Hello,

i know this thread is pretty old, but i have the exact smame problem magic had...

My balls (lol) sticking to the cushion like magic described earlier. also he claimed that disabling the threadding fixed this for him,
unfortunatly that doesnt seem to work for me..

i have tried several different sizes, behavior changed abit, but still it keeps sticking.

i have the same material setup magic mentioned in his first post. any help to fix this problem would nice :).

//snooker

Re: Unit Measures [and other things :)]

Posted: Mon Nov 21, 2011 9:49 pm
by Norbo
Disabling multithreading was targeted at eliminating nondeterminism; it wouldn't have an effect on sticking to things.

If your objects are supposed to be bouncy but not bouncing, it's probably the bounciness velocity threshold. If the velocity magnitude is lower than the threshold, no bounce occurs. The threshold is quite tiny by default. If your simulation is very tiny, the threshold will be much more apparent. It's a good idea to stick within the recommended range of 0.5 to 10 units for individual object dimensions, but if things seem to be working fine otherwise, you could just adjust the CollisionResponseSettings.BouncinessVelocityThreshold.

Re: Unit Measures [and other things :)]

Posted: Tue Nov 22, 2011 1:02 pm
by snooker
Hello Norbo,

that worked!

thank you ;)

//snooker