I have existing geometry in GLTF format. For each geometry I have various LOD versions. I’d like to load these on runtime, visualize them and switch between the LOD levels automatically (in the same way that would happen if I’d import the GLTF into the Godot project and enable the LOD system for it).
To be clear, the main need here is to visualize the LOD levels and to be able to do it runtime. So importing the files into Godot project is not really the solution I’m looking for here.
As starting point, here’s the code with which I’m currently loading the GLTF files on runtime:
private void Load(string filename) {
var doc = new GltfDocument();
var state = new GltfState();
var error = doc.AppendFromFile(filename, state);
if (error != Error.Ok)
{
GD.Print($"When trying to load {filename}: {error}");
return;
}
var rootNode = doc.GenerateScene(state);
AddChild(rootNode);
GD.Print($"Loaded {filename}");
}
Using this approach, I’d like to load each LOD files (that are currently in separate GLTF files) and plug the results somehow into Godot LOD system. Is it possible?
Another approach that came to mind was switching to using a GLTF extension that supports LODs and load just one GLTF file. So if Godot supports that, I’d be quite interested in that as well. Still, runtime only.
I ended up solving my needs by utilizing VisibilityRangeBegin and VisibilityRangeEnd fields. It’s clunkier than using the relative size of the mesh on screen. It also requires that the origin of every mesh is actually in the middle of the mesh. However, it got the job done for me.
To be more exact, here’s the code:
private void Load(string filename, float visRangeBegin, float visRangeEnd, Node container) {
var doc = new GltfDocument();
var state = new GltfState();
var error = doc.AppendFromFile(filename, state);
if (error != Error.Ok)
{
GD.Print($"When trying to load {filename}: {error}");
return;
}
var rootNode = doc.GenerateScene(state);
var meshes = rootNode.FindChildren("*", "GeometryInstance3D");
if (meshes == null || meshes.Count == 0)
{
GD.Print($"Couldn't find any GeometryInstance3D in the GltfDocument in the file {filename}");
}
foreach (var meshNode in meshes)
{
// using visibility ranges assumes that the origin point of the meshes is actually in the center of the mesh data
var mesh = (GeometryInstance3D)meshNode;
mesh.VisibilityRangeBegin = visRangeBegin;
mesh.VisibilityRangeEnd = visRangeEnd;
}
container.AddChild(rootNode);
}