3D collision

I am having lot of issues getting collision of convex mesh running in Monogame. I have general idea how to approach it but I am having some issue with efficiently extracting vertices from ModelMeshPart (+ I need to do collision at level of individual mesh part (custom collision mesh stored and tagged as mesh part)). Any suggestion or resources would be greatly appreciated.

When a model is loaded the vertices are put directly into a VertexBuffer (VRAM) and are not stored in RAM.
To efficiently get the vertices, youā€™d need a custom reader to load your data. Thereā€™s no way to use a custom reader without a custom writer, so youā€™ll need a content pipeline extension project to efficiently get your vertex data. The processor and writer can do exactly the same as the built in ones for Model do, but youā€™ll need a custom reader that mostly does the same as the writer, but also stores the vertices in RAM. In the custom ContentTypeWriter override GetRuntimeReader (example) to specify your custom reader.

1 Like

" I need to do collision at level of individual mesh part "

Assuming you donā€™t want to modify or touch the content reader/writerā€¦ You can get the BoudingSphere of mesh collection, then create a BoundingBox out of BoundingSphere, Iā€™m pretty sure you know how to transformed it from model space to entity world space whenever your model entity scale, rotate and move.

model.Meshes[ Group1 ].BoundingSphere;
model.Meshes[ Group2 ].BoundingSphere;
model.Meshes[ā€¦].BoundingSphere;

1 Like

Yeah I am aware and I am using bounding spheres to determine first layer of collision but once that is confirmed and I need to be much more precise. I am fine with modifying content pipeline, I kinda expected that to be a case and was checking if I am not missing something.

1 Like

Thanks a lot for reference to code. I modified writer/reader once in the past when I was trying something regarding skinned animation but I donā€™t remember exact steps, I will probably work on this today.

1 Like

Hi Guys,

I am soon going to have to add some code to my engine to calculate volumes of meshes, I already have code for this.

It basically creates a tetrahedron for each triangle in a mesh using the centre of the mesh as the fourth point. From this you can calculate the signed volume of the tetrahedron and sum these up to get the volume of the mesh. The result is pretty accurate and is great for calculating point masses and inertia.

A side affect of the code is that you can calculate reasonably accurate collision meshes based on similar code.

A good quick read is this

http://what-when-how.com/advanced-methods-in-computer-graphics/collision-detection-advanced-methods-in-computer-graphics-part-2/

https://n-e-r-v-o-u-s.com/blog/?p=4415

If it becomes an issue for you let me know and I can push it up the todo list.

I am pretty much stuck at ā€œFailed to create processor ā€˜ContentProcessor1ā€™ā€ does pipeline produce any log that would let me know details? Iā€™ve managed to create custom pipeline to use default model processor and modify tag + read it without issue. But the moment I define writer I get stuck on this.

Edit: Scratch that, moment I add any custom writer (no matter if it does anything at all) custom processor dissappears from Pipeline tool. Going to find more references for custom writer.

Edit2: I am frustrated to point of unbelieve at the moment, is this still a thing? https://github.com/MonoGame/MonoGame/issues/1650

using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using System.Collections.Generic;
using WorldEnder;

namespace ModelExtendedPipeline
{
    [ContentTypeWriter]
    public class CollidableDataWriter : ContentTypeWriter<CollidableData>
    {
        protected override void Write(ContentWriter output, CollidableData clip)
        {

        }

        public override string GetRuntimeReader(TargetPlatform targetPlatform)
        {
            return typeof(CollidableDataReader).AssemblyQualifiedName;
        }
    }
}

This is how my barebone writer looks like, the moment I add this class to pipeline whole processor disappears from monogame pipeline tool without pointing out single reason.

You can get that info at run time using GetData(). Each ModelPart in Model.Parts has a VertexBuffer/IndexBuffer.
Here is a sample that loads only the positions from a VertexBuffer (GetPositionsTest)
https://github.com/MonoGame/MonoGame/blob/develop/Test/Framework/Graphics/VertexBufferTest.cs#L279-L295

However GetData might not work on all platforms (GLES in android for example). Here is another example of a similar importer.


It will export a standard Model but If you iterate through each ModelPart , in the Tag field you will find an Object[] with the vertices and indexes.

You can find the binary importer here


Similarly to the GetData() example, you could modify it to save only the positions (Vector3) and throw away Color, TextureCoord, etc. and/or add extra data , like BoundingBoxes.

Remember that you have to iterate the indexBuffer, not the vertexBuffer. Every 3 indices is a triangle and you use those to lookup the positions in the vertex buffer.

There were few more things I wanted to do regarding custom model processor for some time, but I am slowly giving up, I will go for GetData the moment I flip table.

Okay, I got contentProcessor part working by moving Reader into new project, now I am having some issues at loading side, I am going to poke it bit longer.

1 Like

A custom Model processor is nearly impossible. Model/ModelMeshPart/ModelMeshPartCollection are sealed.
Additionally thereā€™s a limitation that doesnā€™t allow to override an existing reader with your own.

Itā€™s possible to swap the VertexBuffer/IndexBuffer with your own, as I have done in DynamicModelProcessor , but thatā€™s as far as you can go. For anything more complicated youā€™d have to write your own model class.

You can use fact that Tag is object and add additional data there.

Indeed! Tag is the only way.

Here we goā€¦ so I was literally stuck for 6 hours on simple fact that reader needs to be in its own dll class, I have no idea why but at this point I donā€™t care.

I believe the reader just needs to be in a dll so it can be referenced by the pipeline tool. Not necessarily itā€™s own dll, but your game is likely not compiled to a dll at all.

1 Like


Altho I am not really fond of algorithm I used.

2 Likes