Program.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. // hierarchy created:
  16. // Mesh1
  17. // Skin1─> Armature1
  18. // Skin2─> Armature2
  19. // Skin3─> Armature3
  20. // Scene
  21. // ├── Armature1
  22. // │ ├── Bone1
  23. // │ ├── Bone2
  24. // │ └── Bone3
  25. // ├── SkinnedMesh1─> Mesh1, Skin1
  26. // ├── Armature2
  27. // │ ├── Bone1
  28. // │ ├── Bone2
  29. // │ └── Bone3
  30. // ├── SkinnedMesh2─> Mesh1, Skin2
  31. // ├── Armature3
  32. // │ ├── Bone1
  33. // │ ├── Bone2
  34. // │ └── Bone3
  35. // └── SkinnedMesh3─> Mesh1, Skin3
  36. private static readonly Random _Randomizer = new Random(17);
  37. static void Main(string[] args)
  38. {
  39. var model = ModelRoot.CreateModel();
  40. var scene = model.UseScene("default");
  41. var mesh = model
  42. .CreateMeshes(CreateMesh(10))
  43. .First();
  44. AddTentacleSkeleton(scene, mesh, Matrix4x4.CreateTranslation(-100, 0, 0), Quaternion.CreateFromYawPitchRoll(0f, 0.2f, 0f));
  45. AddTentacleSkeleton(scene, mesh, Matrix4x4.CreateTranslation( 0, 0, 0), Quaternion.CreateFromYawPitchRoll(0.2f, 0f, 0f));
  46. AddTentacleSkeleton(scene, mesh, Matrix4x4.CreateTranslation( 100, 0, 0), Quaternion.CreateFromYawPitchRoll(0f, 0f, 0.2f));
  47. model.SaveGLB("tentacle.glb");
  48. }
  49. static void AddTentacleSkeleton(Scene scene, Mesh mesh, Matrix4x4 origin, Quaternion anim)
  50. {
  51. var bindings = new List<Node>();
  52. Node skeleton = scene.CreateNode();
  53. skeleton.LocalTransform = origin;
  54. Node bone = skeleton;
  55. for (int i = 0; i < 10; ++i)
  56. {
  57. if (bone == null)
  58. {
  59. bone = skeleton.CreateNode();
  60. }
  61. else
  62. {
  63. bone = bone.CreateNode();
  64. bone.LocalTransform = Matrix4x4.CreateTranslation(0, 10, 0);
  65. }
  66. bone.WithRotationAnimation("Track0", (0, Quaternion.Identity), (1, anim), (2, Quaternion.Identity));
  67. bindings.Add(bone);
  68. }
  69. scene.CreateNode()
  70. .WithMesh(mesh)
  71. .WithSkinBinding(bindings.ToArray());
  72. }
  73. static MESH CreateMesh(int boneCount)
  74. {
  75. var mesh = new MESH("skinned mesh");
  76. var prim = mesh.UsePrimitive(new SharpGLTF.Materials.MaterialBuilder("Default"));
  77. var a0 = default(VERTEX);
  78. var a1 = default(VERTEX);
  79. var a2 = default(VERTEX);
  80. var a3 = default(VERTEX);
  81. for (int i = 0; i < boneCount; ++i)
  82. {
  83. var b0 = new VERTEX(new Vector3(-5, i * 10, -5), Vector4.One, (i, 1));
  84. var b1 = new VERTEX(new Vector3(+5, i * 10, -5), Vector4.One, (i, 1));
  85. var b2 = new VERTEX(new Vector3(+5, i * 10, +5), Vector4.One, (i, 1));
  86. var b3 = new VERTEX(new Vector3(-5, i * 10, +5), Vector4.One, (i, 1));
  87. if (i > 0)
  88. {
  89. prim.AddPolygon(b0, b1, a1, a0);
  90. prim.AddPolygon(b1, b2, a2, a1);
  91. prim.AddPolygon(b2, b3, a3, a2);
  92. prim.AddPolygon(b3, b0, a0, a3);
  93. }
  94. a0 = b0;
  95. a1 = b1;
  96. a2 = b2;
  97. a3 = b3;
  98. }
  99. return mesh;
  100. }
  101. }
  102. }