Search code examples
c#unity-game-enginevolume

Calculating width, height and volume of atypical object


I have atypical objects where I want to calculate its width, height and volume. For the sake of volume i have got this script

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 &lt; mesh.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);
 }

}

As I am not a mathematican so I can't verify that its is working fine and not but one thing is clear that it is not updating the volume calculation if i scale up or down the object. So is this the correct way to calculate object volume? Secondly, I am getting width and height of the object using meshRenderer bounds

Bounds meshBounds = GetComponent<MeshRenderer>().bounds;
float width = meshBounds.size.x;
float height = meshBounds.size.y;

Is this a correct approach for width and height calculation? How can I cross check it.


Solution

  • I have crossed check width and height and volume through revit tool.

    For Width, Height and Breath::

    Bounds meshBounds = GetComponent<MeshRenderer>().bounds;
    float width   = meshBounds.size.x;
    float height  = meshBounds.size.y;
    float breath  =  meshBounds.size.z
    

    In my case i have take MeshRendere bounds you can also calculate it through Collider.

    For Volume:

    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 &lt; mesh.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);
     }