Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

physics contact appears bugged

edited April 28 in Bugs Posts: 171

recommend you watch this video at 0.25 playback speed

i setup a color change algorithm in the collision function, and i change colors based on contact.state, but the results seem to not be correct, the boxes should be green when contact.state is not ENDED and then back to blue/red when ENDED

function Body:collide(contact)
  if self.body == contact.bodyA or self.body == contact.bodyB then
    if contact.state == BEGAN or contact.state == CHANGED then
      local col = Colors.green
      self.demoMesh.mesh.shader.modColor = vec3(col.r/255, col.g/255, col.b/255)
    elseif contact.state == ENDED then
      local col = Colors[self.color]
      self.demoMesh.mesh.shader.modColor = vec3(col.r/255, col.g/255, col.b/255)
    end
  end
end

Comments

  • SimeonSimeon Admin Mod
    Posts: 5,693

    Thanks, I've passed this report onto @John and he says it does look incorrect

  • edited April 30 Posts: 171

    @Simeon @John

    i think this bug is on my side because i’m not keeping track of more than 1 collision, so if more than one occurs and just one of them ends, the body goes to the “off” color even if it’s still touching another body...

    BUT i noticed that CHANGED is never true so that is another bug

    also i noticed using physics.continuous creates a memory leak

    you can test it out using this altered Simple Physics example, touch anywhere to create 100 bodies, then repeatedly press the MOVE button, you will see the memory monitor keeps increasing by small increments and never goes back down to the “starting” memory


    -- Simple Physics -- Use this function to perform your initial setup function setup() print("Hello Physics!") print("Touch the screen to make boxes") parameter.action('clear', clearBodies) parameter.action('move', moveBodies) -- Table to store our physics bodies walls = {} bodies = {} physics.continuous = true -- Create some static boxes (not effected by gravity or collisions) local left = makeBox(WIDTH/4, HEIGHT/2, WIDTH/3, 15, -30) left.type = STATIC local right = makeBox(WIDTH - WIDTH/4, HEIGHT/2, WIDTH/3, 15, 30) right.type = STATIC local floor = makeBox(WIDTH/2, 10, WIDTH, 20, 0) floor.type = STATIC table.insert(walls, left) table.insert(walls, right) table.insert(walls, floor) end -- This function gets called once every frame function draw() -- This sets a dark background color background(40, 40, 50) for k ,body in pairs(walls) do drawBody(body) end -- Draw all our physics bodies for k,body in pairs(bodies) do drawBody(body) end monitor(true) end function touched(touch) -- When you touch the screen, create a random box if touch.state == BEGAN then for i=1, 100 do table.insert(bodies, makeBox(touch.x, touch.y, math.random(5, 50), math.random(5, 50), 0)) end end end -- Helper function to create a box using a polygon body function makeBox(x,y,w,h,r) -- Points are defined in counter-clockwise order local body = physics.body(POLYGON,vec2(-w/2, h/2), vec2(-w/2, -h/2), vec2(w/2, -h/2), vec2(w/2, h/2)) -- Set the body's transform (position, angle) body.x = x body.y = y body.angle = r body.bullet = true --body.sensor = true return body end function moveBodies() for i = 1, #bodies do local demoBody = bodies[i] demoBody.linearVelocity = vec2(0,0) demoBody.angularVelocity = 0 demoBody.angle = 0 local x, y = 600, 600 demoBody.x = math.random(x - 100, x + 100) demoBody.y = math.random(y - 100, y + 100) demoBody.type = DYNAMIC demoBody.sleepingAllowed = false end end function clearBodies() for i=1, #bodies do bodies[i]:destroy() end bodies = {} end -- Helper function to draw a physics body function drawBody(body) -- Push style and transform matrix so we can restore them after pushStyle() pushMatrix() strokeWidth(5) stroke(148, 224, 135, 255) translate(body.x, body.y) rotate(body.angle) -- Draw body based on shape type if body.shapeType == POLYGON then strokeWidth(3.0) local points = body.points for j = 1,#points do a = points[j] b = points[(j % #points)+1] line(a.x, a.y, b.x, b.y) end elseif body.shapeType == CHAIN or body.shapeType == EDGE then strokeWidth(3.0) local points = body.points for j = 1,#points-1 do a = points[j] b = points[j+1] line(a.x, a.y, b.x, b.y) end elseif body.shapeType == CIRCLE then strokeWidth(3.0) line(0,0,body.radius-3,0) ellipse(0,0,body.radius*2) end -- Restore style and transform popMatrix() popStyle() end -- DEV Monitor local monitorQueue = {} function queueMonitor(d, v) monitorQueue[#monitorQueue + 1] = { desc=d, value=v } end function monitor(doCG) queueMonitor('framerate: %.3fms', 1000 * DeltaTime) -- realDT) queueMonitor('frequency: %ifps', math.floor(1 / DeltaTime)) -- realDT)) queueMonitor('memory: %.0fkb', collectgarbage('count')) zLevel(10) fill(30, 30, 30, 150) rect(WIDTH/2 - 100, 70, 200, 80) fill(200, 200, 200, 255) local fullDesc = '' local values = {} for i=1,#monitorQueue do local desc, value = monitorQueue[i].desc, monitorQueue[i].value fullDesc = fullDesc .. desc .. ' \n' values[#values + 1] = value end text(string.format( fullDesc, table.unpack(values) ), WIDTH / 2, 100) if doCG then collectgarbage() end monitorQueue = {} end
  • edited May 12 Posts: 171

    @Simeon i have also noticed that there’s a bug with collision in that sometimes the ENDED event comes before the STARTED event

    it’s caused me some headache trying to account for it, it happens often when there’s a lot of bodies (100+) OR when a collision is really fast (hit and run)

    p.s. turn down your volume or you will get a preview of the music i listen to while coding

    Collision Event order bug, fast

    Codea collision bug, many


    if self.body == contact.bodyA or self.body == contact.bodyB then if contact.state == BEGAN then if self.collisions[contact.id] == 'ended before started' then --print('ended before started') else self.collisions[contact.id] = 'started' self.numCollisions = self.numCollisions + 1 end if self.numCollisions > 0 then print(self.id, 'col began', self.numCollisions) local col = Colors.green if self.demoMesh.shader == 'colorSh' then self.demoMesh.mesh.shader.modColor = vec3L(col.r/255, col.g/255, col.b/255) elseif self.demoMesh.shader == 'fluidCirclesSh' then self.demoMesh.mesh.shader.backgroundColor = vec3L(col.r/255, col.g/255, col.b/255) end end end if contact.state == ENDED then if self.collisions[contact.id] == 'started' then self.collisions[contact.id] = nil self.numCollisions = self.numCollisions - 1 else print('ended before started') self.collisions[contact.id] = 'ended before started' end if self.numCollisions == 0 then print(self.id, 'col ended', self.numCollisions) local col = Colors[self.color] if self.demoMesh.shader == 'colorSh' then self.demoMesh.mesh.shader.modColor = vec3L(col.r/255, col.g/255, col.b/255) elseif self.demoMesh.shader == 'fluidCirclesSh' then self.demoMesh.mesh.shader.backgroundColor = vec3L(col.r/255, col.g/255, col.b/255) end end end end
Sign In or Register to comment.