Joint.java 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package eu.tankernn.gameEngine.animation.animatedModel;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import org.lwjgl.util.vector.Matrix4f;
  5. import eu.tankernn.gameEngine.animation.animation.Animator;
  6. import eu.tankernn.gameEngine.loader.colladaLoader.JointData;
  7. /**
  8. *
  9. * Represents a joint in a "skeleton". It contains the index of the joint which
  10. * determines where in the vertex shader uniform array the joint matrix for this
  11. * joint is loaded up to. It also contains the name of the bone, and a list of
  12. * all the child joints.
  13. *
  14. * The "animatedTransform" matrix is the joint transform that I keep referring
  15. * to in the tutorial. This is the transform that gets loaded up to the vertex
  16. * shader and is used to transform vertices. It is a model-space transform that
  17. * transforms the joint from it's bind (original position, no animation applied)
  18. * position to it's current position in the current pose. Changing this
  19. * transform changes the position/rotation of the joint in the animated entity.
  20. *
  21. * The two other matrices are transforms that are required to calculate the
  22. * "animatedTransform" in the {@link Animator} class. It also has the local bind
  23. * transform which is the original (no pose/animation applied) transform of the
  24. * joint relative to the parent joint (in bone-space).
  25. *
  26. * The "localBindTransform" is the original (bind) transform of the joint
  27. * relative to its parent (in bone-space). The inverseBindTransform is that bind
  28. * transform in model-space, but inversed.
  29. *
  30. * @author Karl
  31. *
  32. */
  33. public class Joint {
  34. public final int index;// ID
  35. public final String name;
  36. public final List<Joint> children = new ArrayList<Joint>();
  37. private Matrix4f animatedTransform = new Matrix4f();
  38. private final Matrix4f localBindTransform;
  39. private Matrix4f inverseBindTransform = new Matrix4f();
  40. /**
  41. * @param index
  42. * - the joint's index (ID).
  43. * @param name
  44. * - the name of the joint. This is how the joint is named in the
  45. * collada file, and so is used to identify which joint a joint
  46. * transform in an animation keyframe refers to.
  47. * @param bindLocalTransform
  48. * - the bone-space transform of the joint in the bind position.
  49. */
  50. public Joint(int index, String name, Matrix4f bindLocalTransform) {
  51. this.index = index;
  52. this.name = name;
  53. this.localBindTransform = bindLocalTransform;
  54. }
  55. public Joint(Joint joint) {
  56. this(joint.index, joint.name, joint.localBindTransform);
  57. for (Joint j : joint.children)
  58. this.children.add(new Joint(j));
  59. }
  60. /**
  61. * Constructs the joint-hierarchy skeleton from the data extracted from the
  62. * collada file.
  63. *
  64. * @param data
  65. * - the joints data from the collada file for the head joint.
  66. * @return The created joint, with all its descendants added.
  67. */
  68. public Joint(JointData data) {
  69. this(data.index, data.nameId, data.bindLocalTransform);
  70. for (JointData child : data.children)
  71. this.addChild(new Joint(child));
  72. }
  73. /**
  74. * Adds a child joint to this joint. Used during the creation of the joint
  75. * hierarchy. Joints can have multiple children, which is why they are
  76. * stored in a list (e.g. a "hand" joint may have multiple "finger" children
  77. * joints).
  78. *
  79. * @param child
  80. * - the new child joint of this joint.
  81. */
  82. public void addChild(Joint child) {
  83. this.children.add(child);
  84. }
  85. /**
  86. * The animated transform is the transform that gets loaded up to the shader
  87. * and is used to deform the vertices of the "skin". It represents the
  88. * transformation from the joint's bind position (original position in
  89. * model-space) to the joint's desired animation pose (also in model-space).
  90. * This matrix is calculated by taking the desired model-space transform of
  91. * the joint and multiplying it by the inverse of the starting model-space
  92. * transform of the joint.
  93. *
  94. * @return The transformation matrix of the joint which is used to deform
  95. * associated vertices of the skin in the shaders.
  96. */
  97. public Matrix4f getAnimatedTransform() {
  98. return animatedTransform;
  99. }
  100. /**
  101. * This method allows those all important "joint transforms" (as I referred
  102. * to them in the tutorial) to be set by the animator. This is used to put
  103. * the joints of the animated model in a certain pose.
  104. *
  105. * @param animationTransform - the new joint transform.
  106. */
  107. public void setAnimationTransform(Matrix4f animationTransform) {
  108. this.animatedTransform = animationTransform;
  109. }
  110. /**
  111. * This returns the inverted model-space bind transform. The bind transform
  112. * is the original model-space transform of the joint (when no animation is
  113. * applied). This returns the inverse of that, which is used to calculate
  114. * the animated transform matrix which gets used to transform vertices in
  115. * the shader.
  116. *
  117. * @return The inverse of the joint's bind transform (in model-space).
  118. */
  119. public Matrix4f getInverseBindTransform() {
  120. return inverseBindTransform;
  121. }
  122. /**
  123. * This is called during set-up, after the joints hierarchy has been
  124. * created. This calculates the model-space bind transform of this joint
  125. * like so: </br>
  126. * </br>
  127. * {@code bindTransform = parentBindTransform * localBindTransform}</br>
  128. * </br>
  129. * where "bindTransform" is the model-space bind transform of this joint,
  130. * "parentBindTransform" is the model-space bind transform of the parent
  131. * joint, and "localBindTransform" is the bone-space bind transform of this
  132. * joint. It then calculates and stores the inverse of this model-space bind
  133. * transform, for use when calculating the final animation transform each
  134. * frame. It then recursively calls the method for all of the children
  135. * joints, so that they too calculate and store their inverse bind-pose
  136. * transform.
  137. *
  138. * @param parentBindTransform
  139. * - the model-space bind transform of the parent joint.
  140. */
  141. protected void calcInverseBindTransform(Matrix4f parentBindTransform) {
  142. Matrix4f bindTransform = Matrix4f.mul(parentBindTransform, localBindTransform, null);
  143. Matrix4f.invert(bindTransform, inverseBindTransform);
  144. for (Joint child : children) {
  145. child.calcInverseBindTransform(bindTransform);
  146. }
  147. }
  148. }