| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Microsoft.Xna.Framework.Graphics;
- namespace SharpGLTF.Runtime
- {
- /// <summary>
- /// Replaces <see cref="ModelMeshPart"/>.
- /// </summary>
- 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
- }
- /// <summary>
- /// Replaces <see cref="ModelMesh"/>
- /// </summary>
- sealed class RuntimeModelMesh
- {
- #region lifecycle
- public RuntimeModelMesh(GraphicsDevice graphicsDevice)
- {
- this._GraphicsDevice = graphicsDevice;
- }
- #endregion
- #region data
- internal GraphicsDevice _GraphicsDevice;
- private readonly List<RuntimeModelMeshPart> _Primitives = new List<RuntimeModelMeshPart>();
- private IReadOnlyList<Effect> _Effects;
- private Microsoft.Xna.Framework.BoundingSphere? _Sphere;
- #endregion
- #region properties
- public IReadOnlyCollection<Effect> 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<RuntimeModelMeshPart> 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
- }
- }
|