Using a DAE mesh for collision

Here’s a quick guide to converting your DAE mesh into collision objects using Blender and dae2collision.


This has only been tested with a simple model from Blender 2.93 using (probably) default settings. Other setups will hopefully work, but no guarantees.

Preparing The Model

Since Defold doesn’t support concave collision shapes, we’ll need to split our model into convex pieces. This, unfortunately, must be done manually, as I haven’t found a working way to automate it. To split a mesh in Blender, you can simply select a part of it in Edit mode, press P, then hit Selection to move that part of the mesh to a new object.

It should look something like this when you’re done:

Since Defold also doesn’t support rendering multiple objects in a mesh, you need a single-object version of your mesh for visuals and a split version for collision.

Now that we’ve got a nicely formatted model, let’s head over to the editor for the easier part.

Using dae2collision

Go ahead and put your new model somewhere in your project (if it’s a particularly complex one, I recommend giving it its own folder) and add dae2collision to your dependencies. It’s a small module meant to be used by an editor script, but it doesn’t come with one. Instead, you can copy the example editor script and tweak the properties to fit your game. Now (assuming you’re using the example), right-click a .dae file and select Generate Collision and it will create one .convexshape per object in the mesh, as well as a game object that puts them all together:

Finally, just add *_generated.go to your game and you’re done!



Thank you so much for this script! As a continuation of the topic, I will add here a link to the excellent 3d level editor, which is completely suitable for creating levels without concave collision shapes - TrenchBroom. It has export in obj format for further conversion in Blender (checked).


Thank you for the great tool!

While making a 3d game with Defold, I found that Bullet Physics has a parameter named “Collision Margin”. Its value is 0.04 in Defold. Why? Take a look at the Bullet Physics manual:

You should take it into account if you are going to use custom collision shapes in Defold. In Blender, you can use the Shrinkwrap modifier that has the “Offset” parameter.

Without that, there is a noticeable offset between physical objects:


Unfortunately, the example does not work for me. The script creates one convex shape file with all the vertices. This happens with both world.dae and world_collision.dae files in the repository. Is it just me or is something broken?

Since there is a Sync Tool, I would like to extend this script to generated convex shapes from buffer files. I don’t know if this should be an improvement of dae2collision, or an additional checkbox in the sync tool, but it would definitely be great.

I don’t know much about blender and python, so I would like to try to improve this script in Lua first. Can I just take the buffer geometry array and translate it straight into a convex shape, I won’t make a mistake here or will there be excess geometry?

The buffer of the box shape exported from Sync Tool looks like 12 triangles with 36 verticles:

    "name": "position",
    "type": "float32",
    "count": 3,
    "data": [

But the convex shape of the box looks like the 8 verticles. Do I really need for some converting here?

My bad, the module wasn’t resetting its XML parser and would only ever output the collision of the first mesh selected (probably world.dae in your case). I’ve pushed a fix and a new release.

There are only 8 vertices in a cube, but Sync Tool seems to list every vertex of every triangle, regardless of if that vertex is shared with another triangle. If you de-duplicate those 36 vertices, you get the 8 that make up the shape:

-96     0       -48
-96     0       48
-96     16      48
-96     16      -48
96      16      48
96      0       48
96      0       -48
96      16      -48
Quick and dirty de-duplicating code
local n = {-96,0,-48,-96,0,48,-96,16,48,-96,0,-48,-96,16,48,-96,16,-48,96,16,48,-96,16,48,-96,0,48,96,16,48,-96,0,48,96,0,48,96,0,48,-96,0,48,-96,0,-48,96,0,48,-96,0,-48,96,0,-48,96,16,-48,-96,16,-48,-96,16,48,96,16,-48,-96,16,48,96,16,48,96,0,-48,-96,0,-48,-96,16,-48,96,0,-48,-96,16,-48,96,16,-48,96,16,-48,96,16,48,96,0,48,96,16,-48,96,0,48,96,0,-48}

local points = {}
for i=1,108,3 do
    table.insert(points, {n[i], n[i+1], n[i+2]})

local deduped = {}

for _,point in ipairs(points) do
    local exists = false
    for _,a in ipairs(deduped) do
        if a[1] == point[1] and a[2] == point[2] and a[3] == point[3] then
            exists = true
    if not exists then table.insert(deduped, point) end


Yes there is a problem with Sync Tool when it exports the verts. It extracts all the verts based on a per triangle on the Blender side. This is needed because some blender objects will not be in tri format and they need to be in tri format for data consistency (multiple position sizes could be supported down the track).

If you change this to only 8 then your UV, Normals and other data streams wont match the verts. Theres a whole range of reasons why Ive taken a “simplistic” approach to the export process (including performance time to extract data and mapping multiple textures to multiple faces). I expect that I will be able to optimize this process as I go. It needs to be remembered that sync_tool is intended to support very complex scenes which just makes supporting everything a little difficult :slight_smile:

It might be sensible to have a checkbox for “Save as Colliders” or something similar. I have something like this already (for the 18), so I’ll let you know if I can get this to work with this tool.

Great work btw, awesome to see the sample above.