MonoGameModelInstance.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Microsoft.Xna.Framework;
  5. using Microsoft.Xna.Framework.Graphics;
  6. namespace SharpGLTF.Runtime
  7. {
  8. public class MonoGameModelInstance
  9. {
  10. #region lifecycle
  11. internal MonoGameModelInstance(MonoGameModelTemplate template, Runtime.SceneInstance instance)
  12. {
  13. _Template = template;
  14. _Instance = instance;
  15. }
  16. #endregion
  17. #region data
  18. private readonly MonoGameModelTemplate _Template;
  19. private readonly Runtime.SceneInstance _Instance;
  20. #endregion
  21. #region properties
  22. public MonoGameModelTemplate Template => _Template;
  23. public Runtime.SceneInstance Controller => _Instance;
  24. #endregion
  25. #region API
  26. public void Draw(Matrix projection, Matrix view, Matrix world)
  27. {
  28. foreach (var d in _Instance.DrawableReferences)
  29. {
  30. Draw(_Template._Meshes[d.Item1], projection, view, world, d.Item2);
  31. }
  32. }
  33. private void Draw(ModelMesh mesh, Matrix projectionXform, Matrix viewXform, Matrix worldXform, Transforms.IGeometryTransform modelXform)
  34. {
  35. if (modelXform is Transforms.SkinTransform skinXform)
  36. {
  37. var skinTransforms = skinXform.SkinMatrices.Select(item => item.ToXna()).ToArray();
  38. foreach (var effect in mesh.Effects)
  39. {
  40. UpdateTransforms(effect, projectionXform, viewXform, worldXform, skinTransforms);
  41. }
  42. }
  43. if (modelXform is Transforms.StaticTransform statXform)
  44. {
  45. var statTransform = statXform.WorldMatrix.ToXna();
  46. worldXform = Matrix.Multiply(statTransform, worldXform);
  47. foreach (var effect in mesh.Effects)
  48. {
  49. UpdateTransforms(effect, projectionXform, viewXform, worldXform);
  50. }
  51. }
  52. mesh.Draw();
  53. }
  54. private static void UpdateTransforms(Effect effect, Matrix projectionXform, Matrix viewXform, Matrix worldXform, Matrix[] skinTransforms = null)
  55. {
  56. if (effect is IEffectMatrices matrices)
  57. {
  58. matrices.Projection = projectionXform;
  59. matrices.View = viewXform;
  60. matrices.World = worldXform;
  61. }
  62. if (effect is SkinnedEffect skin && skinTransforms != null)
  63. {
  64. var xposed = skinTransforms.Select(item => Matrix.Transpose(item)).ToArray();
  65. skin.SetBoneTransforms(skinTransforms);
  66. }
  67. }
  68. #endregion
  69. }
  70. }