package mesh import "math" // BBox returns the axis-aligned bounding box of the mesh. func (m *Mesh) BBox() (min, max Vec3) { if len(m.Verts) == 0 { return Vec3{}, Vec3{} } min, max = m.Verts[0], m.Verts[0] for _, v := range m.Verts[1:] { min = min.Min(v) max = max.Max(v) } return } // SurfaceArea sums the area of all triangles. func (m *Mesh) SurfaceArea() float64 { sum := 0.0 for _, t := range m.Tris { a, b, c := m.Verts[t[0]], m.Verts[t[1]], m.Verts[t[2]] sum += b.Sub(a).Cross(c.Sub(a)).Len() / 2 } return sum } // SignedVolume computes the enclosed volume via the divergence theorem. // Only meaningful for closed meshes; positive when windings face outward. func (m *Mesh) SignedVolume() float64 { sum := 0.0 for _, t := range m.Tris { a, b, c := m.Verts[t[0]], m.Verts[t[1]], m.Verts[t[2]] sum += a.Dot(b.Cross(c)) } return sum / 6 } // Volume is the absolute enclosed volume. func (m *Mesh) Volume() float64 { return math.Abs(m.SignedVolume()) } // SceneBBox returns the bounding box over the given meshes. func SceneBBox(meshes []*Mesh) (min, max Vec3) { first := true for _, m := range meshes { if len(m.Verts) == 0 { continue } mn, mx := m.BBox() if first { min, max = mn, mx first = false } else { min = min.Min(mn) max = max.Max(mx) } } return }