diff --git a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
index 96875df8b..c59ec87fa 100644
--- a/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/AnimatedModelPreview.cs
@@ -48,6 +48,8 @@ namespace FlaxEditor.Viewport.Previews
get => _showNodes;
set
{
+ if (_showNodes == value)
+ return;
_showNodes = value;
if (value)
ShowDebugDraw = true;
@@ -64,6 +66,8 @@ namespace FlaxEditor.Viewport.Previews
get => _showBounds;
set
{
+ if (_showBounds == value)
+ return;
_showBounds = value;
if (value)
ShowDebugDraw = true;
@@ -80,6 +84,8 @@ namespace FlaxEditor.Viewport.Previews
get => _showFloor;
set
{
+ if (_showFloor == value)
+ return;
_showFloor = value;
if (value && !_floorModel)
{
diff --git a/Source/Editor/Viewport/Previews/ModelPreview.cs b/Source/Editor/Viewport/Previews/ModelPreview.cs
index 81c0c350f..c5df9b4d6 100644
--- a/Source/Editor/Viewport/Previews/ModelPreview.cs
+++ b/Source/Editor/Viewport/Previews/ModelPreview.cs
@@ -3,6 +3,8 @@
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.GUI.Input;
using FlaxEngine;
+using FlaxEngine.GUI;
+using FlaxEngine.Utilities;
using Object = FlaxEngine.Object;
namespace FlaxEditor.Viewport.Previews
@@ -13,9 +15,10 @@ namespace FlaxEditor.Viewport.Previews
///
public class ModelPreview : AssetPreview
{
- private ContextMenuButton _showBoundsButton;
- private StaticModel _previewModel;
- private bool _showBounds;
+ private ContextMenuButton _showBoundsButton, _showCurrentLODButton, _showNormalsButton, _showTangentsButton, _showFloorButton;
+ private StaticModel _previewModel, _floorModel;
+ private bool _showBounds, _showCurrentLOD, _showNormals, _showTangents, _showFloor;
+ private MeshDataCache _meshDatas;
///
/// Gets or sets the model asset to preview.
@@ -23,7 +26,19 @@ namespace FlaxEditor.Viewport.Previews
public Model Model
{
get => _previewModel.Model;
- set => _previewModel.Model = value;
+ set
+ {
+ if (_previewModel.Model == value)
+ return;
+ _previewModel.Model = value;
+ _meshDatas?.Dispose();
+ if (_meshDatas != null)
+ {
+ _meshDatas.Dispose();
+ ShowNormals = false;
+ ShowTangents = false;
+ }
+ }
}
///
@@ -32,13 +47,15 @@ namespace FlaxEditor.Viewport.Previews
public StaticModel PreviewActor => _previewModel;
///
- /// Gets or sets a value indicating whether show animated model bounding box debug view.
+ /// Gets or sets a value indicating whether show model bounding box debug view.
///
public bool ShowBounds
{
get => _showBounds;
set
{
+ if (_showBounds == value)
+ return;
_showBounds = value;
if (value)
ShowDebugDraw = true;
@@ -47,6 +64,81 @@ namespace FlaxEditor.Viewport.Previews
}
}
+ ///
+ /// Gets or sets a value indicating whether show model geometry normal vectors debug view.
+ ///
+ public bool ShowNormals
+ {
+ get => _showNormals;
+ set
+ {
+ if (_showNormals == value)
+ return;
+ _showNormals = value;
+ if (value)
+ {
+ ShowDebugDraw = true;
+ if (_meshDatas == null)
+ _meshDatas = new MeshDataCache();
+ _meshDatas.RequestMeshData(_previewModel.Model);
+ }
+ if (_showNormalsButton != null)
+ _showNormalsButton.Checked = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether show model geometry tangent vectors debug view.
+ ///
+ public bool ShowTangents
+ {
+ get => _showTangents;
+ set
+ {
+ if (_showTangents == value)
+ return;
+ _showTangents = value;
+ if (value)
+ {
+ ShowDebugDraw = true;
+ if (_meshDatas == null)
+ _meshDatas = new MeshDataCache();
+ _meshDatas.RequestMeshData(_previewModel.Model);
+ }
+ if (_showTangentsButton != null)
+ _showTangentsButton.Checked = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether show floor model.
+ ///
+ public bool ShowFloor
+ {
+ get => _showFloor;
+ set
+ {
+ if (_showFloor == value)
+ return;
+ _showFloor = value;
+ if (value && !_floorModel)
+ {
+ _floorModel = new StaticModel
+ {
+ Position = new Vector3(0, -25, 0),
+ Scale = new Vector3(5, 0.5f, 5),
+ Model = FlaxEngine.Content.LoadAsync(StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Primitives/Cube.flax")),
+ };
+ }
+ if (value)
+ Task.AddCustomActor(_floorModel);
+ else
+ Task.RemoveCustomActor(_floorModel);
+ if (_showFloorButton != null)
+ _showFloorButton.Checked = value;
+ }
+ }
+
///
/// Gets or sets a value indicating whether scale the model to the normalized bounds.
///
@@ -61,10 +153,7 @@ namespace FlaxEditor.Viewport.Previews
{
Task.Begin += OnBegin;
- // Setup preview scene
_previewModel = new StaticModel();
-
- // Link actors for rendering
Task.AddCustomActor(_previewModel);
if (useWidgets)
@@ -72,6 +161,24 @@ namespace FlaxEditor.Viewport.Previews
// Show Bounds
_showBoundsButton = ViewWidgetShowMenu.AddButton("Bounds", () => ShowBounds = !ShowBounds);
+ // Show Normals
+ _showNormalsButton = ViewWidgetShowMenu.AddButton("Normals", () => ShowNormals = !ShowNormals);
+
+ // Show Tangents
+ _showTangentsButton = ViewWidgetShowMenu.AddButton("Tangents", () => ShowTangents = !ShowTangents);
+
+ // Show Floor
+ _showFloorButton = ViewWidgetShowMenu.AddButton("Floor", button => ShowFloor = !ShowFloor);
+ _showFloorButton.IndexInParent = 1;
+
+ // Show current LOD widget
+ _showCurrentLODButton = ViewWidgetShowMenu.AddButton("Current LOD", button =>
+ {
+ _showCurrentLOD = !_showCurrentLOD;
+ _showCurrentLODButton.Icon = _showCurrentLOD ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
+ });
+ _showCurrentLODButton.IndexInParent = 2;
+
// Preview LOD
{
var previewLOD = ViewWidgetButtonMenu.AddButton("Preview LOD");
@@ -117,6 +224,110 @@ namespace FlaxEditor.Viewport.Previews
{
DebugDraw.DrawWireBox(_previewModel.Box, Color.Violet.RGBMultiplied(0.8f), 0, false);
}
+
+ // Draw normals
+ if (_showNormals && _meshDatas.RequestMeshData(Model))
+ {
+ var meshDatas = _meshDatas.MeshDatas;
+ var lodIndex = ComputeLODIndex(Model);
+ var lod = meshDatas[lodIndex];
+ for (int meshIndex = 0; meshIndex < lod.Length; meshIndex++)
+ {
+ var meshData = lod[meshIndex];
+ for (int i = 0; i < meshData.VertexBuffer.Length; i++)
+ {
+ ref var v = ref meshData.VertexBuffer[i];
+ DebugDraw.DrawLine(v.Position, v.Position + v.Normal, Color.Green);
+ }
+ }
+ }
+
+ // Draw tangents
+ if (_showTangents && _meshDatas.RequestMeshData(Model))
+ {
+ var meshDatas = _meshDatas.MeshDatas;
+ var lodIndex = ComputeLODIndex(Model);
+ var lod = meshDatas[lodIndex];
+ for (int meshIndex = 0; meshIndex < lod.Length; meshIndex++)
+ {
+ var meshData = lod[meshIndex];
+ for (int i = 0; i < meshData.VertexBuffer.Length; i++)
+ {
+ ref var v = ref meshData.VertexBuffer[i];
+ DebugDraw.DrawLine(v.Position, v.Position + v.Tangent, Color.Blue);
+ }
+ }
+ }
+ }
+
+
+ private int ComputeLODIndex(Model model)
+ {
+ if (PreviewActor.ForcedLOD != -1)
+ return PreviewActor.ForcedLOD;
+
+ // Based on RenderTools::ComputeModelLOD
+ CreateProjectionMatrix(out var projectionMatrix);
+ float screenMultiple = 0.5f * Mathf.Max(projectionMatrix.M11, projectionMatrix.M22);
+ var sphere = PreviewActor.Sphere;
+ var viewOrigin = ViewPosition;
+ float distSqr = Vector3.DistanceSquared(ref sphere.Center, ref viewOrigin);
+ var screenRadiusSquared = Mathf.Square(screenMultiple * sphere.Radius) / Mathf.Max(1.0f, distSqr);
+
+ // Check if model is being culled
+ if (Mathf.Square(model.MinScreenSize * 0.5f) > screenRadiusSquared)
+ return -1;
+
+ // Skip if no need to calculate LOD
+ if (model.LoadedLODs == 0)
+ return -1;
+ var lods = model.LODs;
+ if (lods.Length == 0)
+ return -1;
+ if (lods.Length == 1)
+ return 0;
+
+ // Iterate backwards and return the first matching LOD
+ for (int lodIndex = lods.Length - 1; lodIndex >= 0; lodIndex--)
+ {
+ if (Mathf.Square(lods[lodIndex].ScreenSize * 0.5f) >= screenRadiusSquared)
+ {
+ return lodIndex + PreviewActor.LODBias;
+ }
+ }
+
+ return 0;
+ }
+
+ ///
+ public override void Draw()
+ {
+ base.Draw();
+
+ if (_showCurrentLOD)
+ {
+ var asset = Model;
+ var lodIndex = ComputeLODIndex(asset);
+ string text = string.Format("Current LOD: {0}", lodIndex);
+ if (lodIndex != -1)
+ {
+ var lods = asset.LODs;
+ lodIndex = Mathf.Clamp(lodIndex + PreviewActor.LODBias, 0, lods.Length - 1);
+ var lod = lods[lodIndex];
+ int triangleCount = 0, vertexCount = 0;
+ for (int meshIndex = 0; meshIndex < lod.Meshes.Length; meshIndex++)
+ {
+ var mesh = lod.Meshes[meshIndex];
+ triangleCount += mesh.TriangleCount;
+ vertexCount += mesh.VertexCount;
+ }
+ text += string.Format("\nTriangles: {0:N0}\nVertices: {1:N0}", triangleCount, vertexCount);
+ }
+ var font = Style.Current.FontMedium;
+ var pos = new Vector2(10, 50);
+ Render2D.DrawText(font, text, new Rectangle(pos + Vector2.One, Size), Color.Black);
+ Render2D.DrawText(font, text, new Rectangle(pos, Size), Color.White);
+ }
}
///
@@ -135,8 +346,15 @@ namespace FlaxEditor.Viewport.Previews
///
public override void OnDestroy()
{
- // Ensure to cleanup created actor objects
+ Object.Destroy(ref _floorModel);
Object.Destroy(ref _previewModel);
+ _showBoundsButton = null;
+ _showCurrentLODButton = null;
+ _showNormalsButton = null;
+ _showTangentsButton = null;
+ _showFloorButton = null;
+ _meshDatas?.Dispose();
+ _meshDatas = null;
base.OnDestroy();
}
diff --git a/Source/Editor/Windows/Assets/ModelWindow.cs b/Source/Editor/Windows/Assets/ModelWindow.cs
index 5cc6096f0..be7140d61 100644
--- a/Source/Editor/Windows/Assets/ModelWindow.cs
+++ b/Source/Editor/Windows/Assets/ModelWindow.cs
@@ -1,23 +1,17 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
-using System;
using System.Collections.Generic;
using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Xml;
using FlaxEditor.Content;
using FlaxEditor.Content.Import;
using FlaxEditor.CustomEditors;
-using FlaxEditor.CustomEditors.Editors;
using FlaxEditor.GUI;
-using FlaxEditor.GUI.ContextMenu;
-using FlaxEditor.GUI.Tabs;
using FlaxEditor.Scripting;
using FlaxEditor.Viewport.Cameras;
using FlaxEditor.Viewport.Previews;
using FlaxEngine;
using FlaxEngine.GUI;
+using FlaxEngine.Utilities;
using Object = FlaxEngine.Object;
namespace FlaxEditor.Windows.Assets
@@ -32,87 +26,19 @@ namespace FlaxEditor.Windows.Assets
private sealed class Preview : ModelPreview
{
private readonly ModelWindow _window;
- private ContextMenuButton _showFloorButton;
- private ContextMenuButton _showCurrentLODButton;
- private StaticModel _floorModel;
- private bool _showCurrentLOD;
public Preview(ModelWindow window)
: base(true)
{
_window = window;
- // Show floor widget
- _showFloorButton = ViewWidgetShowMenu.AddButton("Floor", button =>
- {
- _floorModel.IsActive = !_floorModel.IsActive;
- _showFloorButton.Icon = _floorModel.IsActive ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
- });
- _showFloorButton.IndexInParent = 1;
-
- // Show current LOD widget
- _showCurrentLODButton = ViewWidgetShowMenu.AddButton("Current LOD", button =>
- {
- _showCurrentLOD = !_showCurrentLOD;
- _showCurrentLODButton.Icon = _showCurrentLOD ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
- });
- _showCurrentLODButton.IndexInParent = 2;
-
- // Floor model
- _floorModel = new StaticModel
- {
- Position = new Vector3(0, -25, 0),
- Scale = new Vector3(5, 0.5f, 5),
- Model = FlaxEngine.Content.LoadAsync(StringUtils.CombinePaths(Globals.EngineContentFolder, "Editor/Primitives/Cube.flax")),
- IsActive = false
- };
- Task.AddCustomActor(_floorModel);
-
// Enable shadows
PreviewLight.ShadowsMode = ShadowsCastingMode.All;
PreviewLight.CascadeCount = 3;
PreviewLight.ShadowsDistance = 2000.0f;
Task.ViewFlags |= ViewFlags.Shadows;
}
-
- private int ComputeLODIndex(Model model)
- {
- if (PreviewActor.ForcedLOD != -1)
- return PreviewActor.ForcedLOD;
-
- // Based on RenderTools::ComputeModelLOD
- CreateProjectionMatrix(out var projectionMatrix);
- float screenMultiple = 0.5f * Mathf.Max(projectionMatrix.M11, projectionMatrix.M22);
- var sphere = PreviewActor.Sphere;
- var viewOrigin = ViewPosition;
- float distSqr = Vector3.DistanceSquared(ref sphere.Center, ref viewOrigin);
- var screenRadiusSquared = Mathf.Square(screenMultiple * sphere.Radius) / Mathf.Max(1.0f, distSqr);
-
- // Check if model is being culled
- if (Mathf.Square(model.MinScreenSize * 0.5f) > screenRadiusSquared)
- return -1;
-
- // Skip if no need to calculate LOD
- if (model.LoadedLODs == 0)
- return -1;
- var lods = model.LODs;
- if (lods.Length == 0)
- return -1;
- if (lods.Length == 1)
- return 0;
-
- // Iterate backwards and return the first matching LOD
- for (int lodIndex = lods.Length - 1; lodIndex >= 0; lodIndex--)
- {
- if (Mathf.Square(lods[lodIndex].ScreenSize * 0.5f) >= screenRadiusSquared)
- {
- return lodIndex + PreviewActor.LODBias;
- }
- }
-
- return 0;
- }
-
+
public override void Draw()
{
base.Draw();
@@ -122,41 +48,7 @@ namespace FlaxEditor.Windows.Assets
if (asset == null || !asset.IsLoaded)
{
Render2D.DrawText(style.FontLarge, "Loading...", new Rectangle(Vector2.Zero, Size), style.ForegroundDisabled, TextAlignment.Center, TextAlignment.Center);
- return;
}
-
- if (_showCurrentLOD)
- {
- var lodIndex = ComputeLODIndex(asset);
- string text = string.Format("Current LOD: {0}", lodIndex);
- if (lodIndex != -1)
- {
- var lods = asset.LODs;
- lodIndex = Mathf.Clamp(lodIndex + PreviewActor.LODBias, 0, lods.Length - 1);
- var lod = lods[lodIndex];
- int triangleCount = 0, vertexCount = 0;
- for (int meshIndex = 0; meshIndex < lod.Meshes.Length; meshIndex++)
- {
- var mesh = lod.Meshes[meshIndex];
- triangleCount += mesh.TriangleCount;
- vertexCount += mesh.VertexCount;
- }
- text += string.Format("\nTriangles: {0:N0}\nVertices: {1:N0}", triangleCount, vertexCount);
- }
- var font = Style.Current.FontMedium;
- var pos = new Vector2(10, 50);
- Render2D.DrawText(font, text, new Rectangle(pos + Vector2.One, Size), Color.Black);
- Render2D.DrawText(font, text, new Rectangle(pos, Size), Color.White);
- }
- }
-
- public override void OnDestroy()
- {
- Object.Destroy(ref _floorModel);
- _showFloorButton = null;
- _showCurrentLODButton = null;
-
- base.OnDestroy();
}
}
@@ -495,7 +387,7 @@ namespace FlaxEditor.Windows.Assets
if (_uvChannel == value)
return;
_uvChannel = value;
- Window.RequestMeshData();
+ Window._meshData?.RequestMeshData(Window._asset);
}
}
@@ -634,7 +526,7 @@ namespace FlaxEditor.Windows.Assets
}
}
- private void DrawMeshUVs(int meshIndex, MeshData meshData)
+ private void DrawMeshUVs(int meshIndex, MeshDataCache.MeshData meshData)
{
var uvScale = Size;
if (meshData.IndexBuffer == null || meshData.VertexBuffer == null)
@@ -642,54 +534,54 @@ namespace FlaxEditor.Windows.Assets
var linesColor = _highlightIndex != -1 && _highlightIndex == meshIndex ? Style.Current.BackgroundSelected : Color.White;
switch (_channel)
{
- case UVChannel.TexCoord:
- for (int i = 0; i < meshData.IndexBuffer.Length; i += 3)
+ case UVChannel.TexCoord:
+ for (int i = 0; i < meshData.IndexBuffer.Length; i += 3)
+ {
+ // Cache triangle indices
+ int i0 = meshData.IndexBuffer[i + 0];
+ int i1 = meshData.IndexBuffer[i + 1];
+ int i2 = meshData.IndexBuffer[i + 2];
+
+ // Cache triangle uvs positions and transform positions to output target
+ Vector2 uv0 = meshData.VertexBuffer[i0].TexCoord * uvScale;
+ Vector2 uv1 = meshData.VertexBuffer[i1].TexCoord * uvScale;
+ Vector2 uv2 = meshData.VertexBuffer[i2].TexCoord * uvScale;
+
+ // Don't draw too small triangles
+ float area = Vector2.TriangleArea(ref uv0, ref uv1, ref uv2);
+ if (area > 10.0f)
{
- // Cache triangle indices
- int i0 = meshData.IndexBuffer[i + 0];
- int i1 = meshData.IndexBuffer[i + 1];
- int i2 = meshData.IndexBuffer[i + 2];
-
- // Cache triangle uvs positions and transform positions to output target
- Vector2 uv0 = meshData.VertexBuffer[i0].TexCoord * uvScale;
- Vector2 uv1 = meshData.VertexBuffer[i1].TexCoord * uvScale;
- Vector2 uv2 = meshData.VertexBuffer[i2].TexCoord * uvScale;
-
- // Don't draw too small triangles
- float area = Vector2.TriangleArea(ref uv0, ref uv1, ref uv2);
- if (area > 10.0f)
- {
- // Draw triangle
- Render2D.DrawLine(uv0, uv1, linesColor);
- Render2D.DrawLine(uv1, uv2, linesColor);
- Render2D.DrawLine(uv2, uv0, linesColor);
- }
+ // Draw triangle
+ Render2D.DrawLine(uv0, uv1, linesColor);
+ Render2D.DrawLine(uv1, uv2, linesColor);
+ Render2D.DrawLine(uv2, uv0, linesColor);
}
- break;
- case UVChannel.LightmapUVs:
- for (int i = 0; i < meshData.IndexBuffer.Length; i += 3)
+ }
+ break;
+ case UVChannel.LightmapUVs:
+ for (int i = 0; i < meshData.IndexBuffer.Length; i += 3)
+ {
+ // Cache triangle indices
+ int i0 = meshData.IndexBuffer[i + 0];
+ int i1 = meshData.IndexBuffer[i + 1];
+ int i2 = meshData.IndexBuffer[i + 2];
+
+ // Cache triangle uvs positions and transform positions to output target
+ Vector2 uv0 = meshData.VertexBuffer[i0].LightmapUVs * uvScale;
+ Vector2 uv1 = meshData.VertexBuffer[i1].LightmapUVs * uvScale;
+ Vector2 uv2 = meshData.VertexBuffer[i2].LightmapUVs * uvScale;
+
+ // Don't draw too small triangles
+ float area = Vector2.TriangleArea(ref uv0, ref uv1, ref uv2);
+ if (area > 3.0f)
{
- // Cache triangle indices
- int i0 = meshData.IndexBuffer[i + 0];
- int i1 = meshData.IndexBuffer[i + 1];
- int i2 = meshData.IndexBuffer[i + 2];
-
- // Cache triangle uvs positions and transform positions to output target
- Vector2 uv0 = meshData.VertexBuffer[i0].LightmapUVs * uvScale;
- Vector2 uv1 = meshData.VertexBuffer[i1].LightmapUVs * uvScale;
- Vector2 uv2 = meshData.VertexBuffer[i2].LightmapUVs * uvScale;
-
- // Don't draw too small triangles
- float area = Vector2.TriangleArea(ref uv0, ref uv1, ref uv2);
- if (area > 3.0f)
- {
- // Draw triangle
- Render2D.DrawLine(uv0, uv1, linesColor);
- Render2D.DrawLine(uv1, uv2, linesColor);
- Render2D.DrawLine(uv2, uv0, linesColor);
- }
+ // Draw triangle
+ Render2D.DrawLine(uv0, uv1, linesColor);
+ Render2D.DrawLine(uv1, uv2, linesColor);
+ Render2D.DrawLine(uv2, uv0, linesColor);
}
- break;
+ }
+ break;
}
}
@@ -701,7 +593,9 @@ namespace FlaxEditor.Windows.Assets
var size = Size;
if (_channel == UVChannel.None || size.MaxValue < 5.0f)
return;
- if (!Proxy.Window.RequestMeshData())
+ if (Proxy.Window._meshData == null)
+ Proxy.Window._meshData = new MeshDataCache();
+ if (!Proxy.Window._meshData.RequestMeshData(Proxy.Window._asset))
{
Invalidate();
Render2D.DrawText(Style.Current.FontMedium, "Loading...", new Rectangle(Vector2.Zero, size), Color.White, TextAlignment.Center, TextAlignment.Center);
@@ -710,7 +604,7 @@ namespace FlaxEditor.Windows.Assets
Render2D.PushClip(new Rectangle(Vector2.Zero, size));
- var meshDatas = Proxy.Window._meshDatas;
+ var meshDatas = Proxy.Window._meshData.MeshDatas;
var lodIndex = Mathf.Clamp(_lod, 0, meshDatas.Length - 1);
var lod = meshDatas[lodIndex];
var mesh = Mathf.Clamp(_mesh, -1, lod.Length - 1);
@@ -833,18 +727,9 @@ namespace FlaxEditor.Windows.Assets
}
}
- private struct MeshData
- {
- public int[] IndexBuffer;
- public Mesh.Vertex[] VertexBuffer;
- }
-
private readonly ModelPreview _preview;
private StaticModel _highlightActor;
-
- private MeshData[][] _meshDatas;
- private bool _meshDatasInProgress;
- private bool _meshDatasCancel;
+ private MeshDataCache _meshData;
///
public ModelWindow(Editor editor, AssetItem item)
@@ -913,68 +798,6 @@ namespace FlaxEditor.Windows.Assets
}
}
- private bool RequestMeshData()
- {
- if (_meshDatasInProgress)
- return false;
- if (_meshDatas != null)
- return true;
- _meshDatasInProgress = true;
- _meshDatasCancel = false;
- Task.Run(new Action(DownloadMeshData));
- return false;
- }
-
- private void WaitForMeshDataRequestEnd()
- {
- if (_meshDatasInProgress)
- {
- _meshDatasCancel = true;
- for (int i = 0; i < 500 && _meshDatasInProgress; i++)
- Thread.Sleep(10);
- }
- }
-
- private void DownloadMeshData()
- {
- try
- {
- if (!_asset)
- {
- _meshDatasInProgress = false;
- return;
- }
- var lods = _asset.LODs;
- _meshDatas = new MeshData[lods.Length][];
-
- for (int lodIndex = 0; lodIndex < lods.Length && !_meshDatasCancel; lodIndex++)
- {
- var lod = lods[lodIndex];
- var meshes = lod.Meshes;
- _meshDatas[lodIndex] = new MeshData[meshes.Length];
-
- for (int meshIndex = 0; meshIndex < meshes.Length && !_meshDatasCancel; meshIndex++)
- {
- var mesh = meshes[meshIndex];
- _meshDatas[lodIndex][meshIndex] = new MeshData
- {
- IndexBuffer = mesh.DownloadIndexBuffer(),
- VertexBuffer = mesh.DownloadVertexBuffer()
- };
- }
- }
- }
- catch (Exception ex)
- {
- Editor.LogWarning("Failed to get mesh data. " + ex.Message);
- Editor.LogWarning(ex);
- }
- finally
- {
- _meshDatasInProgress = false;
- }
- }
-
///
public override void Update(float deltaTime)
{
@@ -1024,7 +847,7 @@ namespace FlaxEditor.Windows.Assets
///
protected override void UnlinkItem()
{
- WaitForMeshDataRequestEnd();
+ _meshData?.WaitForMeshDataRequestEnd();
_preview.Model = null;
_highlightActor.Model = null;
@@ -1056,9 +879,7 @@ namespace FlaxEditor.Windows.Assets
public override void OnItemReimported(ContentItem item)
{
// Discard any old mesh data cache
- WaitForMeshDataRequestEnd();
- _meshDatas = null;
- _meshDatasInProgress = false;
+ _meshData?.Dispose();
base.OnItemReimported(item);
}
@@ -1066,7 +887,8 @@ namespace FlaxEditor.Windows.Assets
///
public override void OnDestroy()
{
- WaitForMeshDataRequestEnd();
+ _meshData?.Dispose();
+ _meshData = null;
base.OnDestroy();