using Godot; using System.Collections; using System.Collections.Generic; namespace Rokojori { public class LODCameraDistanceLevel { public Mesh mesh; public Material material; public float distance; } public class LODBuilder { public enum Mode { CameraDistance } Mode mode = Mode.CameraDistance; public static LODBuilder ByCameraDistance() { var builder = new LODBuilder(); builder.mode = Mode.CameraDistance; return builder; } List levels = new List(); Material material; public LODBuilder SetMaterial( Material material ) { this.material = material; return this; } public LODBuilder Add( float distance, Mesh mesh, Material material = null ) { var level = new LODCameraDistanceLevel { mesh = mesh, distance = distance, material = material }; levels.Add( level ); return this; } public LODNode Create( Node parent, string name = "LOD" ) { var lodNode = parent.CreateChild( name ); var arrangement = new LODArrangement(); levels.Sort( ( a, b ) => Mathf.Sign( a.distance - b.distance ) ); var maxMap = new Dictionary(); for ( int i = 0; i < levels.Count; i++ ) { if ( ( i + 1 ) < levels.Count ) { maxMap[ levels[ i ] ] = levels[ i + 1 ].distance; } else { maxMap[ levels[ i ] ] = 10000f; } } levels[ 0 ].distance = 0; levels.ForEach( ( l )=> { var level = new LODLevel(); var distanceRule = new LODCameraDistanceRule(); distanceRule.minDistance = l.distance; distanceRule.maxDistance = maxMap[ l ]; level.visibilityRules = [ distanceRule ]; level.mesh = l.mesh; level.material = l.material != null ? l.material : material; arrangement.levels = arrangement.levels.Add( level ); } ); lodNode.arrangement = arrangement; return lodNode; } } }