Program.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Numerics;
  5. using SharpGLTF.Schema2;
  6. using SharpGLTF.Geometry;
  7. using SharpGLTF.Geometry.VertexTypes;
  8. namespace InfiniteSkinnedTentacle
  9. {
  10. using VERTEX = VertexBuilder<VertexPosition, VertexColor1, VertexJoints8x4>;
  11. using MESH = MeshBuilder<VertexPosition, VertexColor1, VertexJoints8x4>;
  12. class Program
  13. {
  14. // Skinning use cases and examples: https://github.com/KhronosGroup/glTF/issues/1403
  15. private static readonly Random _Randomizer = new Random(17);
  16. static void Main(string[] args)
  17. {
  18. var model = ModelRoot.CreateModel();
  19. var scene = model.UseScene("default");
  20. var mesh = model
  21. .CreateMeshes(CreateMesh(10))
  22. .First();
  23. AddTentacleSkeleton(scene, mesh, Matrix4x4.CreateTranslation(-100, 0, 0), Quaternion.CreateFromYawPitchRoll(0f, 0.2f, 0f));
  24. AddTentacleSkeleton(scene, mesh, Matrix4x4.CreateTranslation( 0, 0, 0), Quaternion.CreateFromYawPitchRoll(0.2f, 0f, 0f));
  25. AddTentacleSkeleton(scene, mesh, Matrix4x4.CreateTranslation( 100, 0, 0), Quaternion.CreateFromYawPitchRoll(0f, 0f, 0.2f));
  26. model.SaveGLB("tentacle.glb");
  27. }
  28. static void AddTentacleSkeleton(Scene scene, Mesh mesh, Matrix4x4 origin, Quaternion anim)
  29. {
  30. var bindings = new List<Node>();
  31. Node skeleton = scene.CreateNode();
  32. skeleton.LocalTransform = origin;
  33. Node bone = skeleton;
  34. for (int i = 0; i < 10; ++i)
  35. {
  36. if (bone == null)
  37. {
  38. bone = skeleton.CreateNode();
  39. }
  40. else
  41. {
  42. bone = bone.CreateNode();
  43. bone.LocalTransform = Matrix4x4.CreateTranslation(0, 10, 0);
  44. }
  45. bone.WithRotationAnimation("Track0", (0, Quaternion.Identity), (1, anim), (2, Quaternion.Identity));
  46. bindings.Add(bone);
  47. }
  48. var skin = scene.LogicalParent.CreateSkin();
  49. skin.BindJoints(skeleton, bindings.ToArray());
  50. scene.CreateNode()
  51. .WithMesh(mesh)
  52. .WithSkin(skin);
  53. }
  54. static MESH CreateMesh(int boneCount)
  55. {
  56. var mesh = VERTEX.CreateCompatibleMesh("skinned mesh");
  57. var prim = mesh.UsePrimitive(new SharpGLTF.Materials.MaterialBuilder("Default"));
  58. var a0 = default(VERTEX);
  59. var a1 = default(VERTEX);
  60. var a2 = default(VERTEX);
  61. var a3 = default(VERTEX);
  62. for (int i = 0; i < boneCount; ++i)
  63. {
  64. VERTEX b0 = new VERTEX(new Vector3(-5, i * 10, -5), Vector4.One, (i, 1));
  65. VERTEX b1 = new VERTEX(new Vector3(+5, i * 10, -5), Vector4.One, (i, 1));
  66. VERTEX b2 = new VERTEX(new Vector3(+5, i * 10, +5), Vector4.One, (i, 1));
  67. VERTEX b3 = new VERTEX(new Vector3(-5, i * 10, +5), Vector4.One, (i, 1));
  68. if (i > 0)
  69. {
  70. prim.AddPolygon(b0, b1, a1, a0);
  71. prim.AddPolygon(b1, b2, a2, a1);
  72. prim.AddPolygon(b2, b3, a3, a2);
  73. prim.AddPolygon(b3, b0, a0, a3);
  74. }
  75. a0 = b0;
  76. a1 = b1;
  77. a2 = b2;
  78. a3 = b3;
  79. }
  80. return mesh;
  81. }
  82. }
  83. }