Speed issue when stepping physics manually

When i setSpeed(2.0) with setAutoStep(false); i dont know why is does not work with given speed. Here is structure of my code

Scene* GameScene::createScene(){

    auto scene = Scene::createWithPhysics();
    scene->getPhysicsWorld()->setAutoStep(false);
    scene->getPhysicsWorld()->setSpeed(2.0);
    scene->getPhysicsWorld()->setGravity(Vec2(0.0f,-400));
    auto layer = GameScene::create();
    scene->addChild(layer, 1, "Graphics_layer");
    return scene;
}

and update function like this

void GameScene::update(float delta){

/*update code is here not show in this psudeo code */

    auto scene = Director::getInstance()->getRunningScene();
    scene->getPhysicsWorld()->step(delta);
    }

i

If you look at the documentation comments for the function PhysicaWorld::setSpeed()

/**
 * Set the speed of this physics world.
 *
 * @attention if you setAutoStep(false), this won't work.
 * @param speed  A float number. Speed is the rate at which the simulation executes. default value is 1.0.
 */
inline void setSpeed(float speed) { if(speed >= 0.0f) { _speed = speed; } }

You’ll see this feature only works with autoStep enabled. The reason is because PhysicsWorld scales delta time by speed internally during the auto step.

You can replicate this behaviour manually like so:

void GameScene::update(float delta)
{
    /*update code is here not show in this psudeo code */
    float speed = 2;
    auto scene = Director::getInstance()->getRunningScene();
    scene->getPhysicsWorld()->step(delta * speed);
}

However it is also worth noting that if your GameScene::update() is called every frame with a variable dt, the physics simulation will be unstable.

See these discussions for more detail:


http://discuss.cocos2d-x.org/t/does-the-built-in-physics-engine-physicsworld-update-need-a-low-pass-filter-for-dt/21534

1 Like

@almax27 Thanks for the reply , it worked the way you told me , also i did implement low pass filter so for now it is working fine here is how i did it

Scene* GameScene::createScene(){

    float filterFactor = 0.1;
    auto scene = Scene::createWithPhysics();
   
    scene->getPhysicsWorld()->setAutoStep(false);
    scene->getPhysicsWorld()->setUpdateFilterFactor(filterFactor);
    scene->getPhysicsWorld()->setGravity(Vec2(0.0f,-400));
    scene->addChild(layer, 1, "Graphics_layer");
    return scene;
}

void GameScene::update(float delta)
{
    /*update code is here not show in this psudeo code */
    float speed = 2;
    auto scene = Director::getInstance()->getRunningScene();
    scene->getPhysicsWorld()->step(delta * speed);
}

working fine Thanks :smile:

@almax27 stepping physics in update(float delta) with step(delta) or step(2*delta) is causing weird problems with positions and my gamelogic i dont know why , i guess problem is with delta or something i dont know , what if i call step() in a seperate function with should be scheduled by default update rate of physics engine , do you know what is default update rate of physics engine if stepping is done automatically

Thanks

@almax27 alright i decided to isolate stepping from update() so i create another function to step() and it helped , not altering my game logic that much but gives jitters/jerk sometimes here is what i did

low pass_filer: 0.1

Scene* GameScene::createScene(){

    float filterFactor = 0.1;
    auto scene = Scene::createWithPhysics();

    scene->getPhysicsWorld()->setAutoStep(false);
    scene->getPhysicsWorld()->setUpdateFilterFactor(filterFactor);
    scene->getPhysicsWorld()->setGravity(Vec2(0.0f,-400));
    scene->addChild(layer, 1, "Graphics_layer");
    return scene;
}

in init()

schedule(schedule_selector(GameScene::cust_step), (1.0f/60.0f));
this->scheduleUpdate();

void GameScene::cust_step(float dt){
    auto scene = Director::getInstance()->getRunningScene();
    scene->getPhysicsWorld()->step(2*dt);
}

but still its not giving me performance and look what autostepping used to give me.
Note: i’m using chipmunk engine

Thank you

Autostepping is done every frame with a varying interval matching frame interval by default (updateRate=1,speed=1)

You find exact details in the CCPhysicsWorld.cpp source file.

Using a fixed offset for the physics interval will desynchronize it from the frame interval and therefore jittering is expected. As detailed in those threads I linked you, you will need to perform interpolation or extrapolation from physics space to render space in order to smooth out the physics state for each rendered frame.

Any reason you’re not using auto step in the first place?

@almax27 yes i got back to autostepping :grin: