UI/ModelPreview.razor
@using Sandbox;
@using Sandbox.UI;
@namespace CryptidHunt

<root>
</root>

@code
{
    ScenePanel scenePanel;
    bool dragging = false;
    Vector2 dragPosition;
    Rotation startRotation;
    public string ModelPath { get; set; } = "models/items/ammo.vmdl";
    public ModelRenderer Renderer => scenePanel.RenderScene.Components.GetAll<ModelRenderer>().FirstOrDefault();
    public CameraComponent Camera => scenePanel.RenderScene.Components.GetAll<CameraComponent>().FirstOrDefault();
    Vector2 difference;

    public override void Tick()
    {
        base.Tick();

        if (scenePanel == null )
        {
            scenePanel = new ScenePanel("scenes/viewer.scene");
            AddChild(scenePanel);
            scenePanel.SetClass("view", true);
        }

        if ( dragging )
        {
            difference = MousePosition - dragPosition;
            dragPosition = MousePosition;
        }
        else
            difference = Vector2.Zero;

        var yaw = Rotation.FromYaw(difference.x);
        var pitch = Rotation.FromPitch(-difference.y);

        Renderer.WorldRotation = yaw * pitch * Renderer.WorldRotation;
        Renderer.WorldPosition = -Renderer.Model.Bounds.Center * Renderer.WorldRotation;

        if ( Camera.IsValid() )
            Camera.WorldPosition = Vector3.Backward * MathF.Max(MathF.Max(Renderer.Model.Bounds.Extents.x, Renderer.Model.Bounds.Extents.y), Renderer.Model.Bounds.Extents.z ) * 2f;
        Renderer.Model = Model.Load(ModelPath);
    }

    public override void OnButtonEvent(ButtonEvent e)
    {
        base.OnButtonEvent(e);

        if ( e.Button == "mouseleft" )
        {
            if ( e.Pressed )
            {
                dragging = true;
                startRotation = Renderer.WorldRotation;
                dragPosition = MousePosition;
            }
            else
            {
                dragging = false;
            }
        }
    }

    protected override int BuildHash() => System.HashCode.Combine(Time.Now);
}