vpenades / SharpGLTF

glTF reader and writer for .NET Standard
MIT License
467 stars 75 forks source link

bounding volume? #69

Closed bertt closed 3 years ago

bertt commented 3 years ago

Hi, is there some easy method to get the boundingvolume of the glTF? Like the xmin, xmax, ymin, ymax, zmin, zmax of all vertices.

vpenades commented 3 years ago

Not a method, but there's a reasonably simple code snippet. This may change in the future because I am foreseeing the need of a general bounding box solution, because the current bounding box approach of glTF is ill designed, since it only applies to rigid bodies, so it's pointless if it's not general.

This code snippet will evaluate all the triangles of a scene in its final world space positions, so you just need to calculate the bounding box from a collection of points.

var points = SharpGLTF.Schema2.Schema2Toolkit.EvaluateTriangles(model.DefaultScene)
    .SelectMany(item => new[] { item.A.GetGeometry().GetPosition(), item.B.GetGeometry().GetPosition(), item.C.GetGeometry().GetPosition() })
    .Distinct()
    .ToList();

Notice that EvaluateTriangles also accepts an animation track and a time, so you can evaluate the triangles of a specific animated frame.

Pd. I'm considering either renaming Schema2Toolkit to Tookit.... or moving it one level down outside the Schema2 namespace.

bertt commented 3 years ago

ah thanks for the pointer to this method, I'll try this out :-)

vpenades commented 3 years ago

EvaluateTriangles is an extremely powerful method, it's a shame not many people knows about it... it's essentially a full state machine that dumps the final triangles of a given scene, so you can do a lot of things with it: Evaluate volumes, check if the model is watertight, export to OBJ, triangle picking, redirect the triangles to a MeshBuilder so you can create a single mesh from an entire scene...

bertt commented 3 years ago

I've used it immediately. Works excellent 👍 https://github.com/bertt/b3dm.tooling/blob/master/src/b3dm.tooling/Program.cs#L149

vpenades commented 3 years ago

I would suggest you to do EvaluateTriangles().ToList();

Because the "on demand" nature of IEnumerable, you're evaluating the scene two times; one when you do ToArray().Length, and another one when you gather the points.

bertt commented 3 years ago

ok thanks, fixed that