How would one calculate a 3d Mesh volume in Unity?

Basicly, how could I calculate the volume of a 3d Mesh in Unity?

I have found this, pseudocode, I guess (not sure if it's pseudocode, just a guess):

public float SignedVolumeOfTriangle(Vector p1, Vector p2, Vector p3) {
    var v321 = p3.X*p2.Y*p1.Z;
    var v231 = p2.X*p3.Y*p1.Z;
    var v312 = p3.X*p1.Y*p2.Z;
    var v132 = p1.X*p3.Y*p2.Z;
    var v213 = p2.X*p1.Y*p3.Z;
    var v123 = p1.X*p2.Y*p3.Z;
    return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123);
}

P.S. `SignedVolumeOfTriangle();` calculates volume of Tetrahedron, calculated from those triangles. followed by this:

public float VolumeOfMesh(Mesh mesh) {
    var vols = from t in mesh.Triangles
               select SignedVolumeOfTriangle(t.P1, t.P2, t.P3);
    return Math.Abs(vols.Sum());
}

But I have no idea how to translate it to JavaScript or C# for use in Unity... Could someone point me into the right direction on how to do this?

Thanks in advance!

Given your code works as intended, here's how you'd typically use it.

using UnityEngine;

public class MeshVolume : MonoBehaviour
{
    void Start()
    {
        Mesh mesh = GetComponent<MeshFilter>().sharedMesh;
        float volume = VolumeOfMesh(mesh);
        string msg = "The volume of the mesh is " + volume + " cube units.";
        Debug.Log(msg);
    }

    public float SignedVolumeOfTriangle(Vector3 p1, Vector3 p2, Vector3 p3)
    {
        float v321 = p3.x * p2.y * p1.z;
        float v231 = p2.x * p3.y * p1.z;
        float v312 = p3.x * p1.y * p2.z;
        float v132 = p1.x * p3.y * p2.z;
        float v213 = p2.x * p1.y * p3.z;
        float v123 = p1.x * p2.y * p3.z;

        return (1.0f / 6.0f) * (-v321 + v231 + v312 - v132 - v213 + v123);
    }

    public float VolumeOfMesh(Mesh mesh)
    {
        float volume = 0;

        Vector3[] vertices = mesh.vertices;
        int[] triangles = mesh.triangles;

        for (int i = 0; i < triangles.Length; i += 3)
        {
            Vector3 p1 = vertices[triangles[i + 0]];
            Vector3 p2 = vertices[triangles[i + 1]];
            Vector3 p3 = vertices[triangles[i + 2]];
            volume += SignedVolumeOfTriangle(p1, p2, p3);
        }
        return Mathf.Abs(volume);
    }
}

To me, it sounds like there is a bit of explanation needed about how and why this formula works since we do have some assumptions. Basically, it is using the vectorial equation for the computation of the volume of a tetrahedron, explained and illustrated here:

This assumes that the vectors a, b and c define the edges of the tetrahedron and not the point coordinates of its vertices.
*Note: If you assume that the 4th point of the tetrahedron is on the origin, then you can use a, b and c as the coordinates of the vertices. Otherwise, if you have 4 vertices coordinates (let’s call them d,e,f,g), you can use the same equation but you should use: a = e-d; b = f-d; c=g-d. *

Also, please be aware that this equation works only with convex volume. You should envision to use the volume computation through voxelization (explained here: Triangle mesh voxelization - Wolfire Games Blog) if you want something more robust to complex shapes (but be aware that it is much slower to compute). However, I did not found an easy to use implementation, all those I found were giving compile errors in complex codes and I did not have time to figure it out.

Note2: @HoverX : Using Unity’s RigidBody SetDensity method computes, to my understanding the volume of the Collider’s box of your mesh (generally a Capsule). So it is a very coarse approximation.

So, implementing the same volume computation using the 4 vertices of the tetrahedron and defining the fourth vertex of every tetrahedron as the center of mass of the later, one gets the following implementation:

    using UnityEngine;

    public float SignedVolumeOfTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 o)
    {
        Vector3 v1 = p1 - o;
        Vector3 v2 = p2 - o;
        Vector3 v3 = p3 - o;

        return Vector3.Dot(Vector3.Cross(v1, v2), v3) / 6f; ;
    }

    public float VolumeOfMesh(Mesh mesh)
    {
        float volume = 0;
        Vector3[] vertices = mesh.vertices;
        int[] triangles = mesh.triangles;

        Vector3 o = new Vector3(0f, 0f, 0f);
        // Computing the center mass of the polyhedron as the fourth element of each mesh
        for (int i = 0; i < triangles.Length; i++)
        {
            o += vertices[triangles*];*

}
o = o / mesh.triangles.Length;

// Computing the sum of the volumes of all the sub-polyhedrons
for (int i = 0; i < triangles.Length; i += 3)
{
Vector3 p1 = vertices[triangles[i + 0]];
Vector3 p2 = vertices[triangles[i + 1]];
Vector3 p3 = vertices[triangles[i + 2]];
volume += SignedVolumeOfTriangle(p1, p2, p3, o);
}
return Mathf.Abs(volume);
}

Actually, that looks to me as valid C# code. By the looks of it, it should work (Given you have such a Mesh class). You might have to resolve namespaces System and System.Linq though.

I am not quite sure what you are looking to do, this seems to calculate the volume of a mesh (cubic units), was that just what you had in mind? Take a look at the Unity3d Mesh reference to see how you could get the triangles.

For a rough (over-)estimate, you can use the bounding volume ...

float volume = mesh.bounds.size.x * mesh.bounds.size.y * mesh.bounds.size.z;

This won't work for all purposes, but could be useful, depending what you need to do.