Answers for "How would one calculate a 3d Mesh volume in Unity?"
http://answers.unity.com/questions/52664/how-would-one-calculate-a-3d-mesh-volume-in-unity.html
The latest answers for the question "How would one calculate a 3d Mesh volume in Unity?"Answer by matteo1000g
http://answers.unity.com/answers/1556445/view.html
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:
https://math.stackexchange.com/questions/1603651/volume-of-tetrahedron-using-cross-and-dot-product
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: http://blog.wolfire.com/2009/11/Triangle-mesh-voxelization) 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 < mesh.triangles.Length; i++)
{
o += vertices[triangles[i]];
}
o = o / mesh.triangles.Length;
// Computing the sum of the volumes of all the sub-polyhedrons
for (int i = 0; i < 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, o);
}
return Mathf.Abs(volume);
}Tue, 25 Sep 2018 08:59:07 GMTmatteo1000gAnswer by Statement
http://answers.unity.com/answers/52733/view.html
<p>Given your code works as intended, here's how you'd typically use it.</p>
<pre><code>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 < 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);
}
}
</code></pre>Thu, 17 Mar 2011 00:34:04 GMTStatementAnswer by yoyo
http://answers.unity.com/answers/52679/view.html
<p>For a rough (over-)estimate, you can use the bounding volume ...</p>
<pre><code>float volume = mesh.bounds.size.x * mesh.bounds.size.y * mesh.bounds.size.z;
</code></pre>
<p>This won't work for all purposes, but could be useful, depending what you need to do.</p>Wed, 16 Mar 2011 20:16:08 GMTyoyoAnswer by Statement
http://answers.unity.com/answers/52666/view.html
<p>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. </p>
<p>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 <a href="http://unity3d.com/support/documentation/ScriptReference/Mesh.html" rel="nofollow">Mesh</a> reference to see how you could get the triangles.</p>Wed, 16 Mar 2011 19:25:42 GMTStatement