// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
using FlaxEditor.GUI.Input;
using FlaxEngine;
using Object = FlaxEngine.Object;
namespace FlaxEditor.Viewport.Previews
{
///
/// Model Base asset preview editor viewport.
///
///
public class ModelBasePreview : AssetPreview
{
///
/// Gets or sets the model asset to preview.
///
public ModelBase Asset
{
get => (ModelBase)StaticModel.Model ?? AnimatedModel.SkinnedModel;
set
{
StaticModel.Model = value as Model;
AnimatedModel.SkinnedModel = value as SkinnedModel;
}
}
///
/// The static model for display.
///
public StaticModel StaticModel;
///
/// The animated model for display.
///
public AnimatedModel AnimatedModel;
///
/// Gets or sets a value indicating whether scale the model to the normalized bounds.
///
public bool ScaleToFit { get; set; } = true;
///
/// Initializes a new instance of the class.
///
/// if set to true use widgets.
public ModelBasePreview(bool useWidgets)
: base(useWidgets)
{
Task.Begin += OnBegin;
// Setup preview scene
StaticModel = new StaticModel();
AnimatedModel = new AnimatedModel();
// Link actors for rendering
Task.AddCustomActor(StaticModel);
Task.AddCustomActor(AnimatedModel);
if (useWidgets)
{
// Preview LOD
{
var previewLOD = ViewWidgetButtonMenu.AddButton("Preview LOD");
var previewLODValue = new IntValueBox(-1, 90, 2, 70.0f, -1, 10, 0.02f)
{
Parent = previewLOD
};
previewLODValue.ValueChanged += () =>
{
StaticModel.ForcedLOD = previewLODValue.Value;
AnimatedModel.ForcedLOD = previewLODValue.Value;
};
ViewWidgetButtonMenu.VisibleChanged += control => previewLODValue.Value = StaticModel.ForcedLOD;
}
}
}
private void OnBegin(RenderTask task, GPUContext context)
{
var position = Vector3.Zero;
var scale = Vector3.One;
// Update preview model scale to fit the preview
var model = Asset;
if (ScaleToFit && model && model.IsLoaded)
{
float targetSize = 50.0f;
BoundingBox box = model is Model ? ((Model)model).GetBox() : ((SkinnedModel)model).GetBox();
float maxSize = Mathf.Max(0.001f, box.Size.MaxValue);
scale = new Vector3(targetSize / maxSize);
position = box.Center * (-0.5f * scale.X) + new Vector3(0, -10, 0);
}
StaticModel.Transform = new Transform(position, StaticModel.Orientation, scale);
AnimatedModel.Transform = new Transform(position, AnimatedModel.Orientation, scale);
}
///
public override bool OnKeyDown(KeyboardKeys key)
{
switch (key)
{
case KeyboardKeys.F:
// Pay respect..
ViewportCamera.SetArcBallView(StaticModel.Model != null ? StaticModel.Box : AnimatedModel.Box);
break;
}
return base.OnKeyDown(key);
}
///
public override void OnDestroy()
{
// Ensure to cleanup created actor objects
Object.Destroy(ref StaticModel);
Object.Destroy(ref AnimatedModel);
base.OnDestroy();
}
}
}