Hi, in my particular case I wan’t to find out the volume of a simple cube (or other primitive) partially “merged” with a complex mesh of undefined complexity, although convex; I want to subtract the intersection to the cube to find out its remaining volume. Furthermore, this needs to run on phones and in realtime; but I don’t really need an exact calculation (although the error margin can not be huge).
I’ve been looking into boolean operations, but the fact that the mesh is not made out of primitives and that I need to rely on plugins to operate in unity makes me feel that there must be something else.
Example of my basic case as seed from a side view, I wan’t to find out the inside volume of the cube:
Yes, this is a quite difficult problem to solve. I doubt there are any reliable approximation methods which always work. The usual straight forward approach would involve some advanced algorithms:
- First you need to clip your mesh so the resulting mesh only contains the “wanted” volume. This first step is the most complicated. You basically need a CSG intersect algorithm which can create a new mesh out of the intersection of two (boolean operation). You should clip the more complex mesh on the simple mesh. So all triangles of the complex mesh outside the simple mesh are ignored. The triangles which intersect the simple mesh need to be clipped. So new vertices need to be calculated and new triangle faces created.
- Once you have your final mesh You might want to test if the mesh is a convex or concave mesh. If it’s concave you need to split it into several convex meshes.
- Once you have only convex volume meshes you can simply pick the center of each sub mesh and treat each triangle of the mesh as a tetrahedron. This does only work with convex meshes. The sum of those tje volumes of all those tetrahedrons is your wanted volume.
- To calculate the volume of a tetrahedron you just need to use the tripple product and divide by 6. The link that Eno Khaon posted above also uses the tripple product, but calculates it “manually”.
The tripple procuct in Unity would look like this, given the 4 corner points of our tetrahedron:
public static float CalcVolumeTetrahedron(Vector3 p0, Vector3 p1,Vector3 p2,Vector3 p3)
{
Vector3 a = p1-p0;
Vector3 b = p2-p0;
Vector3 c = p3-p0;
return Mathf.Abs(Vector3.Dot(Vector3.Cross(a,b),c) / 6f);
}
The Mathf.Abs
is needed, otherwise the volume could be negative depending on the order of the vertices.
I don’t think there’s a simpler way to do this.
One very rough approximation would be to create a voxel grid around your mesh and do a “contains check”. This however can be a bit tricky for concave meshes so you might want to split the complex mesh into several convex meshes. So you would have to check every point inside the simple mesh if it’s inside of any of the convex meshes. Finally just count those which are inside and divide by the total number of voxels inside the simple mesh. The smaller your voxel grid is the better the approximation but the computational complexity increases by the power of 3.
A point is inside a convex mesh if the point is behind all planes that each triangle create. Unity’s Plane struct might be helpful here.