Physics goes slow after a bit

http://www.youtube.com/watch?v=AK4WHbm6q3c&sns=em

I was playing around with the physics stuff and got a nice simulation, only to find that after a few iterations it starts going really slowly. But it’s not doing anything different so somewhere it is accumulatong a drag. How do I get rid of that?

Video above, code below.



-- Use this function to perform your initial setup
displayMode(FULLSCREEN)
function setup()
    sand = {}
    scalefactor = 2
    radius = 7
    nradius = 2
    gap = 2*(radius+nradius+5)
    grains = 0
    watch("grains")
    mgrains = 100
    w = 200
    h = 300
    x =  - w/2
    y =  - h/2
    ground = {physics.body(POLYGON, 
        vec2(x,y+20), 
        vec2(x,y), 
        vec2(x+w,y), 
        vec2(x+w,y+20)),
        physics.body(POLYGON, 
        vec2(x,y+20), 
        vec2(x+20,y+20), 
        vec2(x+20,y+h-20), 
        vec2(x,y+h-20)),
        physics.body(POLYGON, 
        vec2(x+w,y+20), 
        vec2(x+w-20,y+20), 
        vec2(x+w-20,y+h-20), 
        vec2(x+w,y+h-20)),
        physics.body(POLYGON, 
        vec2(x+w,y+h-20), 
        vec2(x+w,y+h), 
        vec2(x,y+h), 
        vec2(x,y+h-20)),
        physics.body(POLYGON,
            vec2(x+20+gap,y+h/2+40),
            vec2(x+w-20-gap,y+h/2-30),
            vec2(x+w-20-gap,y+h/2-40),
            vec2(x+20+gap,y+h/2+30)
        )
        }
    for k,v in ipairs(ground) do
        v.type = STATIC
        v.restitution = .5
    end
    t = 0
    physics.gravity(vec2(0,0))
    physics.iterations(1,1)
    flip = 1
    gstrength = .5
    --startRecording()
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)
    translate(WIDTH/2,HEIGHT/2)
    scale(2)
    -- This sets the line thickness
    strokeWidth(20)
    stroke(0, 76, 255, 255)
    noFill()
    rect(x,y,w,h)
    noStroke()
    
    ellipseMode(RADIUS)
    -- Do your drawing here
    local a = 10*vec2(UserAcceleration.x,UserAcceleration.y)
    local g = flip*gstrength*vec2(Gravity.x,Gravity.y)
    for k,v in ipairs(sand) do
        fill(191 + 64*v.info.gdir, 0, 0, 255)
        ellipse(v.x,v.y,v.radius)
        v:applyForce(a + v.info.gdir*g)
    end
    if grains < mgrains then
    if ElapsedTime - t > .1 then
        t = ElapsedTime
        grains = grains + 1
        addGrain()
    end
    end
end

function addGrain()
    local s = 
            physics.body(CIRCLE,
                radius - nradius+ 2*nradius*math.random()*math.random())
        s.x = math.random(x+40,x+w-40)
        
        s.friction = 0
        s.info = {}
        if math.random() < .5 then
            s.info.gdir = -1
            s.y = y+3*h/4
        else
            s.info.gdir = 1
            s.y = y+h/4
        end
        table.insert(sand,s)
end

function touched(touch)
    if touch.tapCount == 2 then
        --stopRecording()
    end
    if touch.state == BEGAN then
        flip = - flip
    end
end

tap screen to flip gravity.

Hi Andrew, thanks for pointing this out, I think there may be an issue with the way Codea caches physics contacts, which may be causing the slow down. I’ll use this example to help debug the code.

Cool example :slight_smile:

John, that gives me hope that it might be fixable! Great. I seemed to hit another barrier with about 200 objects in that it was slow right from the start, but I guess that there’s always going to be a limit on the number of objects one can use.

However, I guess that there are going to be some optimisations. As you can see in the code, I put the iterations down to 1 but this didn’t make any difference in this case, presumably it would have done if the caching hadn’t overwhelmed it. What other optimisations could one use for something where time is of the essence? Is there a particular shape that is easiest to work with? Particular settings of parameters that are fastest to compute the dynamics for?

Peter, thanks. I was aiming for one of those “sand” pictures, but hit the limit so went for a “bubble” one instead. If John can fix the slow, I’ll try to make it more realistic. Simulating fluid resistance would be the first step, I think.