MonoGameModelInstance.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Microsoft.Xna.Framework;
  5. using Microsoft.Xna.Framework.Graphics;
  6. #if USINGMONOGAMEMODEL
  7. using MODELMESH = Microsoft.Xna.Framework.Graphics.ModelMesh;
  8. using MODELMESHPART = Microsoft.Xna.Framework.Graphics.ModelMeshPart;
  9. #else
  10. using MODELMESH = SharpGLTF.Runtime.ModelMeshReplacement;
  11. using MODELMESHPART = SharpGLTF.Runtime.ModelMeshPartReplacement;
  12. #endif
  13. namespace SharpGLTF.Runtime
  14. {
  15. public sealed class MonoGameModelInstance
  16. {
  17. #region lifecycle
  18. internal MonoGameModelInstance(MonoGameModelTemplate template, SceneInstance instance)
  19. {
  20. _Template = template;
  21. _Controller = instance;
  22. }
  23. #endregion
  24. #region data
  25. private readonly MonoGameModelTemplate _Template;
  26. private readonly SceneInstance _Controller;
  27. #endregion
  28. #region properties
  29. /// <summary>
  30. /// Gets a reference to the template used to create this <see cref="MonoGameModelInstance"/>.
  31. /// </summary>
  32. public MonoGameModelTemplate Template => _Template;
  33. /// <summary>
  34. /// Gets a reference to the animation controller of this <see cref="MonoGameModelInstance"/>.
  35. /// </summary>
  36. public SceneInstance Controller => _Controller;
  37. #endregion
  38. #region API
  39. /// <summary>
  40. /// Draws this <see cref="MonoGameModelInstance"/> into the current <see cref="GraphicsDevice"/>.
  41. /// </summary>
  42. /// <param name="projection">The projection matrix.</param>
  43. /// <param name="view">The view matrix.</param>
  44. /// <param name="world">The world matrix.</param>
  45. public void Draw(Matrix projection, Matrix view, Matrix world)
  46. {
  47. foreach (var d in _Controller.DrawableInstances)
  48. {
  49. Draw(_Template._Meshes[d.Template.LogicalMeshIndex], projection, view, world, d.Transform);
  50. }
  51. }
  52. private void Draw(MODELMESH mesh, Matrix projectionXform, Matrix viewXform, Matrix worldXform, Transforms.IGeometryTransform modelXform)
  53. {
  54. if (modelXform is Transforms.SkinnedTransform skinXform)
  55. {
  56. var skinTransforms = skinXform.SkinMatrices.Select(item => item.ToXna()).ToArray();
  57. foreach (var effect in mesh.Effects)
  58. {
  59. UpdateTransforms(effect, projectionXform, viewXform, worldXform, skinTransforms);
  60. }
  61. }
  62. if (modelXform is Transforms.RigidTransform statXform)
  63. {
  64. var statTransform = statXform.WorldMatrix.ToXna();
  65. worldXform = Matrix.Multiply(statTransform, worldXform);
  66. foreach (var effect in mesh.Effects)
  67. {
  68. UpdateTransforms(effect, projectionXform, viewXform, worldXform);
  69. }
  70. }
  71. mesh.Draw();
  72. }
  73. private static void UpdateTransforms(Effect effect, Matrix projectionXform, Matrix viewXform, Matrix worldXform, Matrix[] skinTransforms = null)
  74. {
  75. if (effect is IEffectMatrices matrices)
  76. {
  77. matrices.Projection = projectionXform;
  78. matrices.View = viewXform;
  79. matrices.World = worldXform;
  80. }
  81. if (effect is SkinnedEffect skin && skinTransforms != null)
  82. {
  83. var xposed = skinTransforms.Select(item => Matrix.Transpose(item)).ToArray();
  84. skin.SetBoneTransforms(skinTransforms);
  85. }
  86. }
  87. #endregion
  88. }
  89. }