Does speed of movement also influence collision detection?

Hi…

I m trying to make carrom board game.

When user launches the striker to hit a coin, then I witness that sometimes collision happens while sometimes it just passes thru.

I observe that if speed is higher(as per my code greater the distance between two larger the velocity vector imparted to striker) collison is not happening.



Does speed play a role in collision detection?



Manish

Yes of course, when you move further in one frame than the objects width you will just go through. Ccd makes sweep checks to avoid that, you can enable it using setCcdThreshold() on your rigid bodies.

///here is my code in simpleInitApp method







bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);

/*

  • Create board

    /

    board_shape = new Box(Vector3f.ZERO, 1, .05f, 1);

    board = new Geometry(“Board”, board_shape);

    Material carrom_mat = new Material(assetManager,

    “Common/MatDefs/Misc/Unshaded.j3md”);

    carrom_mat.setColor(“Color”, new ColorRGBA(255 / 255f, 255 / 255f,

    153 / 253f, 0));

    board.setMaterial(carrom_mat);

    /

  • Add physics to board for physics simulation

    /

    board_phy = new RigidBodyControl(0.0f);

    board.addControl(board_phy);

    if (board.getControl(RigidBodyControl.class) != null) {

    ((RigidBodyControl)board.getControl(RigidBodyControl.class)).setKinematic(true);//its

    // a kinematic rigidbody

    // so unaaffected by forces, gravity or collisions

    ((RigidBodyControl) board.getControl(RigidBodyControl.class))

    .setFriction(.5f);

    }

    bulletAppState.getPhysicsSpace().add(board_phy);



    rootNode.attachChild(board);



    /

  • Create border of board

    /

    wall_shape = new Box(Vector3f.ZERO, 1, .04f, .025f);

    wall = new Geometry(“Wall”, wall_shape);

    Material wall_mat = new Material(assetManager,

    “Common/MatDefs/Misc/Unshaded.j3md”);

    wall_mat.setColor(“Color”, ColorRGBA.Brown);

    wall.setMaterial(wall_mat);

    // wall.scale(.7f);

    wall.move(0, .09f, -1);

    wall_phy = new RigidBodyControl(0.0f);

    wall.addControl(wall_phy);

    if (wall.getControl(RigidBodyControl.class) != null) {

    ((RigidBodyControl) wall.getControl(RigidBodyControl.class))

    .setKinematic(true);

    ((RigidBodyControl) wall.getControl(RigidBodyControl.class))

    .setFriction(.1f);

    ((RigidBodyControl) wall.getControl(RigidBodyControl.class))

    .setRestitution(.2f);

    }

    bulletAppState.getPhysicsSpace().add(wall_phy);

    rootNode.attachChild(wall);



    /

  • Create striker

    /

    striker_shape = new Cylinder(200, 50, .075f, .05f, true);

    striker = new Geometry(“Striker”, striker_shape);

    Material striker_mat = new Material(assetManager,

    “Common/MatDefs/Misc/Unshaded.j3md”);

    striker_mat.setColor(“Color”, ColorRGBA.LightGray);

    striker.setMaterial(striker_mat);

    striker.move(0, .125f, .75f);

    striker.rotate(-FastMath.HALF_PI, 0, 0);

    /

  • Add physics to striker for physics simulation

    /

    collisionshape_striker = CollisionShapeFactory

    .createDynamicMeshShape(striker);

    striker_phy = new RigidBodyControl(collisionshape_striker, 1f);

    striker.addControl(striker_phy);

    if (striker.getControl(RigidBodyControl.class) != null) {

    ((RigidBodyControl) striker.getControl(RigidBodyControl.class))

    .setFriction(.1f);

    ((RigidBodyControl) striker.getControl(RigidBodyControl.class))

    .setRestitution(.01f);

    }

    bulletAppState.getPhysicsSpace().add(striker);

    rootNode.attachChild(striker);

    /

  • Create coin

    /

    coin_shape = new Cylinder(200, 50, .05f, .05f, true);

    coin = new Geometry(“Coin”, coin_shape);

    Material coin_mat = new Material(assetManager,

    “Common/MatDefs/Misc/Unshaded.j3md”);

    coin_mat.setColor(“Color”, ColorRGBA.Red);

    coin.setMaterial(coin_mat);

    coin.move(0, .052f, 0);

    coin.rotate(-FastMath.HALF_PI, 0, 0);

    /

  • Add physics to coin for physics simulation

    */

    collisionshape_coin = CollisionShapeFactory

    .createDynamicMeshShape(coin);

    coin_phy = new RigidBodyControl(collisionshape_coin, 0.5f);

    coin.addControl(coin_phy);

    bulletAppState.getPhysicsSpace().add(coin);

    bulletAppState.getPhysicsSpace().enableDebug(assetManager);

    rootNode.attachChild(coin);

oh thanks normen…i will play with setCcdThreshold and see what happens.

hi…for both striker and coin i set setCcdMotionThreshold(1f)…but i don’t see much difference.



m i supposed to do somethign lese too?

As well as I know ccd is only in the native bullet, but was never implemented in jbullet.

Thats not true but the sweepSphere is a bit wonky in jbullet. Try enabling ccd on both objects. It works better in native bullet though the native bullet adapter itself isn’t 100% working yet.

i did it for both striker and coin…

is there anything wrong with my code…its posted above…and then i added ccd code to it further for both objects…

may be my collision shapes r an issue?i have used createDynamicMeshShape and they both r cylindrical…

I think ccd only works for static objects in jbullet and only to a certain extent for kinematic objects in native bullet. If you really want to make sure that a collision between a dynamic and a kinematic object is detected, you have to …

  • set the accuracy so that the kinetic object cannot move through the dynamic object in one physics tick
  • update the physics location / rotation in every physics tick (jme updates only in update()).



    A had this problem and it gave me sleepless nights. It can be read here.
@survivor said:
- update the physics location / rotation in every physics tick (jme updates only in update()).

Huh? What do you mean by that? update() is always called more often than physicsTick()

both objects are dynamic for me as they both have masses and kinematic is not set to true…

doing that would make them immobile,isn’t which is last thing i would want in carrom game…

Well in native it works fine and the interface is good enough for settings the ccd ^^. at least I can assure you that static collison work. A static mesh in my case.

The swept interface is not in jbullet tho, and dynamic dynamic is probably not working right, since there is no hitprediction but just a sweptcasting for each object sequentially. To do dynamic dynamic you would need to first predict it at any given time there might be the possibility that the bounding boxes overlap on the path from one tick to the next, and then calculate this for the affected objects in several substeps.)



(NOTE we always use the sequential sover, a parallel solver might cover this, but is highly experimental even in the native version and the java interface does not support it at all)

hmmm…now it is becomign more and more deep for me…speed, collision shapes, physics tick(i don’t have much idea of it),kinematics, dyamics…

all mixed up…

nobody said game development is easy ^^

Oh how cute, look at how innocent he sees the world of 3d and gaming :slight_smile:

His hope for fast succes is not yet buried under a load of despair XD.

I can still remember when I joined this forum and kinda felt the same.



Good news is, everything is logical and while it i a lot, you will also learn a large amount of probably quite valueable stuff, even for complelty other projects.

@normen said:
Huh? What do you mean by that? update() is always called more often than physicsTick()

update() is called every frame. A physics tick is defined by accuracy (default 60 Hz) and MaxSubSteps. If you have a default accuracy of 60 Hz and throttle your frame rate to 10 fps, then you will have 6 physics ticks per frame (if MaxSubSteps >= 6). You can test it quite easily with this pseudo code:
[java]
private BulletAppState bulletAppState;
private AtomicInteger physicsTickCounter = new AtomicInteger();

public void setSettings(AppSettings settings {
settings.setFrameRate(10);
super.setSettings(settings);
}

public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.getPhysicsSpace().setAccuracy(1f / 60f);
bulletAppState.getPhysicsSpace().setMaxSubSteps(10); // higher than needed
bulletAppState.getPhysicsSpace().addTickListener(this);
}

public void simpleUpdate(float tpf)
{
int ticks = physicsTickCounter.getAndSet(0);
Logger.getLogger("").severe("****: " + ticks);
}

public void physicsTick(PhysicsSpace ps, float f)
{
physicsTickCounter.incrementAndGet();
}
[/java]
'update()' calls 'dynamicsWorld.stepSimulation(time, maxSteps, accuracy);' but the physics core generates sub steps as needed if fps < accuracy and if MaxSubSteps is high enough. PhysicsTickListener.physicsTick() is called on every sub step or "internal tick".

You need to adjust the accuracy and MaxSubSteps so that even the fastest kinematic object can't move through other objects in one internal tick. And you have to make sure that the location / rotation of the kinematic objects are up-to-date before an internal tick occurs, which can be done in PhysicsTickListener.prePhysicsTick().

@mghildiy said:
both objects are dynamic for me as they both have masses and kinematic is not set to true....
doing that would make them immobile,isn't which is last thing i would want in carrom game..

Yes, in your case (just checked what carrom actually is :D) it makes sense to make the board static and the striker and coins dynamic. No need for kinematic objects. Sorry if I confused you.

so what am i missing here…

i have made both the bodies dynamic with non zero mass…i have imparted collision shapes to them and even did ccd thing…

what else should i do here

You could try if increasing the accuracy helps:

[java]

bulletAppState.getPhysicsSpace().setAccuracy(1f / 1000f);

bulletAppState.getPhysicsSpace().setMaxSubSteps(100);

[/java]



But I think if you set ccd to the radius of your coins, it should work.

1 Like
@survivor said:
update() is called every frame. A physics tick is defined by accuracy (default 60 Hz) and MaxSubSteps. If you have a default accuracy of 60 Hz and throttle your frame rate to 10 fps, then you will have 6 physics ticks per frame (if MaxSubSteps >= 6). You can test it quite easily with this pseudo

Lol, right. I wrote that code myself so I should know better ^^ What I actually meant is that the physics space is only updated each frame but indeed it calls the physics update as often as necessary to keep the framerate, up to the maxSubSteps, yes. Had it backwards here.