Hexagons

After the earlier discussion about hexagons, I made a small library for showing a hexagon grid. Current features are to draw tiles, fill items in a range to determine range of weapons for example, find out field of view, to know if an enemy can see you, draw a line from a to b, and an a*-search to find the shortest path. In the code I have a small guy moving if you have the move toggle on in the demo. Just have one toggle to true at the same time.

The algorithms are not so optimized, but seems fast even though.

https://gist.github.com/tnlogy/8846921

Now I’m thinking about how to texture the tiles in the best way?

@tnlogy - the problem is obviously that textures are square, and meshes require a lot of triangles.

One option might be to create rectangular meshes, and use a shader to only draw the texture inside a hexagonal shape inside each rectangle.

This requires code to test if a point is inside a hexagon, such as this

http://www.playchilla.com/how-to-check-if-a-point-is-inside-a-hexagon

Then you just place your hexagons and the shader takes care of the details.

@Ignatz that’s the site I got my detection method for my color picker :stuck_out_tongue: I lost the site and thus never got to check if my question got answered. It never got answered but I was able to answer it myself :slight_smile:

but back on-topic…
You can ad 4 more triangles to the mesh…
(the ones who’d complete the hexagon and make a square out of it) but set their color to alpha 0…
Then to add textures… you can just use the corners of those trianlges… because… as @Ignatz said, it’s a square…
(note that the texture itself should then be so that it only contains something in the hexagon part…)

my solution so far has been to use a square texture, and then create uv coordinates with .5,.5 in the middle of the hexagon and make it fit inside the square. but my new problem is how to make a texture with several hexagons tile nicely. still working on that :slight_smile:

Easier to describe it with code. Here the texture doesnt match…

function setup()
    size = 100
    local vs,uvs = {},{}
    for i=1,6 do
        local a = i/6 * math.pi * 2
        table.insert(vs, vec2(math.cos(a), math.sin(a)) * size)
        table.insert(uvs, -vec2(math.cos(a),math.sin(a))*.5)
    end
    hexagon = mesh()
    hexagon.vertices = triangulate(vs)
    hexagon.texCoords = triangulate(uvs)
    hexagon.texture = readImage("Cargo Bot:Starry Background")
end

function draw()
    translate(WIDTH/2,HEIGHT/2)
    hexagon:draw()
    translate(size * 3/2, size * math.sqrt(3)/2)
    hexagon:draw()   
end

But this works fine! :slight_smile:

hexShader = shader([[
    uniform mat4 modelViewProjection;
    uniform mat4 m;
    attribute vec4 position;
    attribute vec4 color;
    attribute vec2 texCoord;
    varying lowp vec4 vColor;
    varying highp vec2 vTexCoord;
        
    void main() {
        vColor = color;
        vTexCoord = (m*normalize(position)*.5).xy;
        gl_Position = modelViewProjection * position;
    }
]], [[
    uniform lowp sampler2D texture;
    varying lowp vec4 vColor;
    varying highp vec2 vTexCoord;
         
    void main() {
        lowp vec4 res = texture2D(texture, vTexCoord);
        gl_FragColor = res;
    }
]])

function setup()
    size = 100
    local vs,uvs = {},{}
    for i=1,6 do
        local a = i/6 * math.pi * 2
        table.insert(vs, vec2(math.cos(a), math.sin(a)) * size)
        table.insert(uvs, -vec2(math.cos(a),math.sin(a))*.5)
    end
    hexagon = mesh()
    hexagon.vertices = triangulate(vs)
    hexagon.texCoords = triangulate(uvs)
    hexagon.shader = hexShader
    hexagon.texture = readImage("Cargo Bot:Starry Background")
end

function draw()
    translate(WIDTH/2,HEIGHT/2)
    hexagon.shader.m = modelMatrix()
    hexagon:draw()
    translate(size * 3/2, size * math.sqrt(3)/2)
    hexagon.shader.m = modelMatrix()
    hexagon:draw()   
end

@tnlogy Let me get this straight. You have a tiling image which you want to display but using hexagons as the base shape, not squares. Is that right?

If the image tiles as a square then you can’t have a single hexagon that will do the job. Different hexagons would need different texture coordinates. If you get the relative sizes right, it might be that you’d need two hexagons - I’d need to think about that.

But you could create an image that would tile as a hexagon, then it would work just fine. The image itself would have to be square, but the significant part would be an inscribed hexagon and that’s what you would see.

Because squares and hexagons tile the plane in a different way, going from one to the other is not trivial. So it may be best to find or create an image that is specially designed for hexagons.

(Posted the above before you posted the second)

Ah, in the second then you are setting the texture coordinates according to where the mesh ends up on the screen, so you’re imaging a texture on the screen and simply picking up the part that the hexagon sees. If you look at the individual hexagons then you’ll see what I was talking about: the two hexagons do not display the same image.

thanks for the elaborate comment, I found it hard to describe it, thanks for the help to make it clearer. :slight_smile: now I use modelspace to base the coordinates on.