using NativeEngine;
namespace Sandbox;
///
/// A box which can be used to explicitly control scene visibility.
/// There are two modes:
/// 1. Cull inside, hide any objects fully inside the box (excluder)
/// 2. Cull outside, hide any objects not intersecting any cull boxes marked cull outside (includer)
///
public sealed class SceneCullingBox : IValid
{
///
/// Cull mode, either inside or outside
///
public enum CullMode
{
///
/// Hide any objects fully inside the box
///
Inside,
///
/// Hide any objects not intersecting any boxes
///
Outside,
}
///
/// Is this culling box valid, exists inside a scene world.
///
public bool IsValid => _boxId != 0 && World.IsValid();
///
/// The scene world this culling box belongs to.
///
public SceneWorld World { get; internal set; }
///
/// Position and rotation of this box, scale will scale the box size
///
public Transform Transform
{
get => _transform;
set { _transform = value; Update(); }
}
///
/// Size of this box, transform scale will scale this size
///
public Vector3 Size
{
get => _size;
set { _size = value; Update(); }
}
///
/// Cull mode, either inside or outside
///
public CullMode Mode
{
get => _mode;
set { _mode = value; Update(); }
}
internal uint _boxId;
internal Transform _transform;
internal Vector3 _size;
internal CullMode _mode;
///
/// Create a scene culling box.
/// Each scene world can have a list of boxes which can be used to explicitly cull objects inside or outside the boxes.
///
public SceneCullingBox( SceneWorld world, Transform transform, Vector3 size, CullMode mode )
{
World = world;
_boxId = 0;
_transform = transform;
_size = size;
_mode = mode;
Update();
}
///
/// Delete this culling box. You shouldn't access it anymore.
///
public void Delete()
{
if ( !IsValid )
return;
CSceneSystem.RemoveCullingBox( World, _boxId );
_boxId = 0;
_transform = default;
_size = default;
_mode = default;
World = null;
}
internal void Update()
{
if ( !World.IsValid() )
return;
if ( _boxId != 0 )
{
CSceneSystem.RemoveCullingBox( World, _boxId );
_boxId = 0;
}
_boxId = CSceneSystem.AddCullingBox( World,
_mode == CullMode.Inside,
_transform.Position, _transform.Rotation.Angles(),
_size * _transform.Scale );
}
}