Box2D glitch or something wrong with the code?

Tap many times and eventually the boxes will start going in each other.

-- Boxes

function setup()
    rectMode(CENTER)
    boxes={}
    ground=physics.body(EDGE, vec2(0, 0), vec2(WIDTH, 0))
    rEdge=physics.body(EDGE, vec2(WIDTH, 0), vec2(WIDTH, HEIGHT))
    lEdge=physics.body(EDGE, vec2(0, 0), vec2(0, HEIGHT))
end


function draw()
    background(40, 40, 50)
    strokeWidth(5)
    for a,b in pairs(boxes) do
        pushMatrix()
        translate(b.x, b.y)
        rotate(b.angle)
        rect(0, 0, 100, 100)
        popMatrix()
    end
end

function createBox(x, y, sizeX, sizeY)
    pushMatrix()
    translate(x, y)
    local p=physics.body(POLYGON, vec2(0-sizeX/2, 0-sizeY/2), vec2(sizeX/2, 0-sizeY/2), vec2(0-sizeX/2, sizeY/2), vec2(sizeX/2, sizeY/2))
    p.type=DYNAMIC
    p.position=vec2(x, y)
    p.fixedRotation=false
    popMatrix()
    return p
end

function touched(t)
    if t.state==BEGAN then
        table.insert(boxes, createBox(t.x, t.y, 100, 100))
    end
end

I haven’t run this, but have you checked you aren’t creating boxes on top of each other (ie they should be completely separate)?

Off the top of my head, an easy way to do this might be to

  1. check the touch point is not inside an existing box
  2. generate a new box at the touch point with size 1x1
  3. grow the box to its full size over a few frames

This means you can generate new boxes very close to existing boxes, and as they grow to full size, they will “push” the other boxes out of the way

@Ignatz I create boxes completely separate, but they still go into each other. Let me see if I can provide a video.

Here:

https://www.youtube.com/embed/GBmgOBeWdoA

@Saturn031000 it’s to do with how you’re drawing the boxes, not box2D. Try using rectMode(CENTER) in the draw function.

@Luatee No difference. Same result as in the video above.

@Saturn031000 my bad I didn’t see you had it in setup(). What you were doing is creating the vertices in the wrong order, it should be like this (anti-clockwise order):

local p=physics.body(POLYGON, vec2(-sizeX/2, -sizeY/2), vec2(sizeX/2, -sizeY/2), vec2(sizeX/2, sizeY/2), vec2(-sizeX/2, sizeY/2))

@Luatee Thanks. That is confusing.

@Saturn031000 No problem, I should have tested it to begin with. You can create vertices in clockwise order but according to Erin Catto Box2D’s solving algorithm works better if they’re set in anti-clockwise.

@Saturn031000 Here’s your code, but I added the polygon function to draw the actual object you set up. The rect you display is in blue, but the actual object is in white. You can see why the rects overlap.


-- Boxes

displayMode(FULLSCREEN)

function setup()
    rectMode(CENTER)
    boxes={}
    ground=physics.body(EDGE, vec2(0, 0), vec2(WIDTH, 0))
    rEdge=physics.body(EDGE, vec2(WIDTH, 0), vec2(WIDTH, HEIGHT))
    lEdge=physics.body(EDGE, vec2(0, 0), vec2(0, HEIGHT))
end


function draw()
    background(40, 40, 50)
    strokeWidth(5)
    for a,b in pairs(boxes) do
        --pushMatrix()
        --translate(b.x, b.y)
        --rotate(b.angle)
        --rect(0, 0, 100, 100)
        --popMatrix()
        polygon(b)
    end
end

function polygon(p)
    pushMatrix()
    noFill()
    stroke(25, 0, 255, 255)
    translate(p.x, p.y)
    rect(0, 0, 100, 100)
    rotate(p.angle)
    local j=p.points[#p.points]
    stroke(255)
    for i = 1, #p.points do
        local a = p.points[i]
        line(j.x, j.y, a.x, a.y)
        j=p.points[i]
    end
    popMatrix()
end

function createBox(x, y, sizeX, sizeY)
    pushMatrix()
    translate(x, y)
    local p=physics.body(POLYGON, vec2(0-sizeX/2, 0-sizeY/2), vec2(sizeX/2, 0-sizeY/2), vec2(0-sizeX/2, sizeY/2), vec2(sizeX/2, sizeY/2))
    p.type=DYNAMIC
    p.position=vec2(x, y)
    p.fixedRotation=false
    popMatrix()
    return p
end

function touched(t)
    if t.state==BEGAN then
        table.insert(boxes, createBox(t.x, t.y, 100, 100))
    end
end

@dave1707 - nice work =D>

@Ignatz Thanks. Once you display the actual object, everything makes sense. I don’t think it matters in what order you create the points. You just have to draw them correctly.

I don’t think I’m drawing the object in the correct order. I think there’s one side that isn’t being drawn. Every now and then the object looks like it’s not sitting how it should, like it’s resting on an invisible side.

It looks like the left side of the box is there for the collisions, but not being drawn. I’ll have to break out the paper and pencil and draw things by hand and see what’s actually happening.

@dave1707 I see the problem with the invisible side. And I think the order of point creation does matter because once I changed it, it worked fine.

Also, nice program.

@Saturn031000 I’ll have to check on this more. I didn’t think the order, clockwise or counterclockwise mattered as mentioned above. I know you can’t just define the points in a random order.

I tried creating the points in both clockwise and counterclockwise order with no difference in the way it worked. The triangulate function used to required the points to be drawn in a certain direction, but that was corrected in a previous version. So at this point, I don’t see a problem with creating the points in either direction. You just can’t reverse the direction and cross lines.

@dave1707 - my understanding is that the “anti clockwise” rule is used by OpenGL only in 3D drawing, because when your camera can be set at any position around your scene, it needs some way of figuring out which triangles face the camera, and which face away (and don’t need to be drawn). So the rule is that anti clockwise triangles face the camera and clockwise triangles fade away - then, if you put the camera on the opposite side of your scene, the clockwise triangles will become anti clockwise triangles and will be drawn, which is exactly what we want.

So the order shouldn’t matter here.

@Ignatz very inetresting. Could you prove it with a simple code?

I had personal experience when I was drawing a 3D object and some of the triangles came out black, but fixed that code. I can prove it more easily, using google

The OpenGL Programming guide says “By convention, polygons whose vertices appear in counterclockwise order on the screen are called front-facing.”

From the OpenGL docs - “Triangle primitives after all transformation steps have a particular facing. This is defined by the order of the three vertices that make up the triangle, as well as their apparent order on-screen. Triangles can be discarded based on their apparent facing, a process known as Face Culling.”

And another explanation - “There’s one important thing to consider when choosing the order of vertices: winding. When rendering a model, on average around half of the triangles that make up the model are facing away from the camera. If the model isn’t transparent, there’s no way to see these triangles. So to speed up rendering, the GPU can ignore all triangles that face away from the camera, potentially halving the amount of work to do.
The way the GPU checks if a triangle is facing away is by looking at the winding direction of the triangle. It does this by considering if the camera’s view of the triangle sees the vertices in clockwise or anti-clockwise (some people call it counter-clockwise) order. In OpenGL, anti-clockwise is the default winding direction for rendering, so any clockwise faces are skipped.”