using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework.Graphics;
namespace SharpGLTF.Runtime
{
///
/// Replaces .
///
sealed class RuntimeModelMeshPart
{
#region lifecycle
internal RuntimeModelMeshPart(RuntimeModelMesh parent)
{
_Parent = parent;
}
#endregion
#region data
private readonly RuntimeModelMesh _Parent;
private Effect _Effect;
private IndexBuffer _IndexBuffer;
private int _IndexOffset;
private int _PrimitiveCount;
private VertexBuffer _VertexBuffer;
private int _VertexOffset;
private int _VertexCount;
public object Tag { get; set; }
#endregion
#region properties
public Effect Effect
{
get => _Effect;
set
{
if (_Effect == value) return;
_Effect = value;
_Parent.InvalidateEffectCollection(); // if we change this property, we need to invalidate the parent's effect collection.
}
}
public GraphicsDevice Device => _Parent._GraphicsDevice;
#endregion
#region API
public void SetVertexBuffer(VertexBuffer vb, int offset, int count)
{
this._VertexBuffer = vb;
this._VertexOffset = offset;
this._VertexCount = count;
}
public void SetIndexBuffer(IndexBuffer ib, int offset, int count)
{
this._IndexBuffer = ib;
this._IndexOffset = offset;
this._PrimitiveCount = count;
}
public void Draw(GraphicsDevice device)
{
if (_PrimitiveCount > 0)
{
device.SetVertexBuffer(_VertexBuffer);
device.Indices = _IndexBuffer;
for (int j = 0; j < _Effect.CurrentTechnique.Passes.Count; j++)
{
_Effect.CurrentTechnique.Passes[j].Apply();
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, _VertexOffset, _IndexOffset, _PrimitiveCount);
}
}
}
#endregion
}
///
/// Replaces
///
sealed class RuntimeModelMesh
{
#region lifecycle
public RuntimeModelMesh(GraphicsDevice graphicsDevice)
{
this._GraphicsDevice = graphicsDevice;
}
#endregion
#region data
internal GraphicsDevice _GraphicsDevice;
private readonly List _Primitives = new List();
private IReadOnlyList _Effects;
private Microsoft.Xna.Framework.BoundingSphere? _Sphere;
#endregion
#region properties
public IReadOnlyCollection Effects
{
get
{
if (_Effects != null) return _Effects;
// Create the shared effects collection on demand.
_Effects = _Primitives
.Select(item => item.Effect)
.Distinct()
.ToArray();
return _Effects;
}
}
public Microsoft.Xna.Framework.BoundingSphere BoundingSphere
{
set => _Sphere = value;
get
{
if (_Sphere.HasValue) return _Sphere.Value;
return default;
}
}
public IReadOnlyList MeshParts => _Primitives;
public string Name { get; set; }
public ModelBone ParentBone { get; set; }
public object Tag { get; set; }
#endregion
#region API
internal void InvalidateEffectCollection() { _Effects = null; }
public RuntimeModelMeshPart CreateMeshPart()
{
var primitive = new RuntimeModelMeshPart(this);
_Primitives.Add(primitive);
InvalidateEffectCollection();
_Sphere = null;
return primitive;
}
public void Draw()
{
for (int i = 0; i < _Primitives.Count; i++)
{
_Primitives[i].Draw(_GraphicsDevice);
}
}
#endregion
}
}