using UnityEngine;
using UnityEngine.Polybrush;
namespace UnityEditor.Polybrush
{
///
/// Handle mesh preview. Use it to load a static preview from a native Unity Mesh,
/// PolybrushMesh or ProBuilderMesh.
///
///
/// Launch page
public class MeshPreview
{
///
/// Preview default size.
///
static readonly Vector2Int k_PreviewSize = new Vector2Int(128, 128);
internal enum State
{
Loading,
Loaded,
Cannot_Load
}
///
/// Returns the loaded preview texture.
/// If there's none, returns a white texture as fallback.
///
internal Texture2D previewTexture
{
get
{
if (m_previewState == State.Loaded && m_PreviewTexture != null)
return m_PreviewTexture;
return Texture2D.whiteTexture;
}
}
///
/// Current preview state.
///
internal State CurrentPreviewState
{
get { return m_previewState; }
}
///
/// Instance current state.
///
State m_previewState = State.Loading;
///
/// Loaded preview texture.
///
Texture2D m_PreviewTexture;
///
/// Reference to the asset associated to this preview.
///
Object m_Asset = null;
internal MeshPreview(Object asset)
{
m_Asset = asset;
m_PreviewTexture = Texture2D.whiteTexture;
SetState(State.Loading);
}
///
/// Update the current state of the mesh preview.
/// As AssetPreview API is asynchronous, we need to keep requesting the asset preview
/// until we have it. Once texture is loaded, current state of the instance moves
/// to Status.Loaded.
///
internal void UpdatePreview()
{
switch (m_previewState)
{
case State.Loading:
if (ProBuilderBridge.ProBuilderExists() && ProBuilderInterface.IsProBuilderObject(m_Asset as GameObject))
m_PreviewTexture = GenerateProBuilderPreview();
else if (PolyEditorUtility.IsPolybrushObject(m_Asset as GameObject))
m_PreviewTexture = GeneratePreview();
else
m_PreviewTexture = AssetPreview.GetAssetPreview(m_Asset);
if (previewTexture != null)
SetState(State.Loaded);
break;
case State.Loaded:
// Failsafe as AssetPreview can return white textures while loading
// and erase that texture from memory once the right texture is available.
if (m_PreviewTexture == null)
SetState(State.Loading);
break;
}
}
///
/// Generate a static preview for a PolybrushMesh.
/// A mesh is generated from a PolybrushMesh then feed to a default Mesh editor.
///
/// Static preview of the given PolybrushMesh.
internal Texture2D GeneratePreview()
{
PolybrushMesh castTarget = (m_Asset as GameObject).GetComponent();
Mesh mesh = castTarget.storedMesh;
Editor meshEditor = Editor.CreateEditor(mesh);
Texture2D preview = meshEditor.RenderStaticPreview(null, null, k_PreviewSize.x, k_PreviewSize.y);
ScriptableObject.DestroyImmediate(meshEditor);
return preview;
}
///
/// Generate a static preview for a ProBuilderMesh.
///
/// Static preview of the given ProBuilderMesh.
internal Texture2D GenerateProBuilderPreview()
{
GameObject copy = GameObject.Instantiate(m_Asset as GameObject);
copy.hideFlags = HideFlags.HideAndDontSave;
ProBuilderBridge.ToMesh(copy);
ProBuilderBridge.Refresh(copy);
MeshFilter mf = copy.GetComponent();
Editor meshEditor = Editor.CreateEditor(mf.sharedMesh);
Texture2D preview = meshEditor.RenderStaticPreview(null, null, k_PreviewSize.x, k_PreviewSize.y);
ScriptableObject.DestroyImmediate(meshEditor);
ScriptableObject.DestroyImmediate(copy);
return preview;
}
private void SetState(State newState)
{
m_previewState = newState;
}
}
}