using NativeEngine; namespace Sandbox; /// /// A scene object that allows custom rendering within a scene world. /// public class SceneCustomObject : SceneObject { internal NativeEngine.CManagedSceneObject managedNative; internal SceneCustomObject( HandleCreationData _ ) { } public SceneCustomObject( SceneWorld sceneWorld ) { Assert.IsValid( sceneWorld ); using ( var h = IHandle.MakeNextHandle( this ) ) { CManagedSceneObject.Create( sceneWorld ); if ( native.IsValid ) { // Start off with infinite bounds so it will actually get rendered // if the user forgets/doesn't need bounds. native.SetBoundsInfinite(); } } } internal unsafe override void OnNativeInit( CSceneObject ptr ) { base.OnNativeInit( ptr ); managedNative = (NativeEngine.CManagedSceneObject)ptr; } internal override void OnNativeDestroy() { managedNative = default; base.OnNativeDestroy(); } internal void RenderInternal() { if ( !this.IsValid() ) return; try { RenderSceneObject(); } catch ( System.Exception e ) { Log.Error( e ); } } /// /// Called by default version of . /// public Action RenderOverride; /// /// Called when this scene object needs to be rendered. /// Invokes by default. See the library for a starting point. /// public virtual void RenderSceneObject() { RenderOverride?.Invoke( this ); } } internal static class SceneCustomObjectRender { internal static void RenderObject( ManagedRenderSetup_t setup, SceneCustomObject obj ) { if ( obj is null ) return; using ( new Graphics.Scope( in setup ) ) { obj.RenderInternal(); } } }