123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package eu.tankernn.gameEngine.animation;
- import org.lwjgl.util.vector.Matrix4f;
- import org.lwjgl.util.vector.Vector3f;
- /**
- *
- * Represents the local bone-space transform of a joint at a certain keyframe
- * during an animation. This includes the position and rotation of the joint,
- * relative to the parent joint (for the root joint it's relative to the model's
- * origin, seeing as the root joint has no parent). The transform is stored as a
- * position vector and a quaternion (rotation) so that these values can be
- * easily interpolated, a functionality that this class also provides.
- *
- * @author Karl
- *
- */
- public class JointTransform {
- // remember, this position and rotation are relative to the parent bone!
- private final Vector3f position;
- private final Quaternion rotation;
- /**
- *
- * @param position
- * - the position of the joint relative to the parent joint
- * (bone-space) at a certain keyframe. For example, if this joint
- * is at (5, 12, 0) in the model's coordinate system, and the
- * parent of this joint is at (2, 8, 0), then the position of
- * this joint relative to the parent is (3, 4, 0).
- * @param rotation
- * - the rotation of the joint relative to the parent joint
- * (bone-space) at a certain keyframe.
- */
- public JointTransform(Vector3f position, Quaternion rotation) {
- this.position = position;
- this.rotation = rotation;
- }
- /**
- * @param localTransform
- * - the joint's local-transform at a certain keyframe of an
- * animation.
- */
- public JointTransform(Matrix4f localTransform) {
- this.position = new Vector3f(localTransform.m30, localTransform.m31, localTransform.m32);
- this.rotation = new Quaternion(localTransform);
- }
- /**
- * In this method the bone-space transform matrix is constructed by
- * translating an identity matrix using the position variable and then
- * applying the rotation. The rotation is applied by first converting the
- * quaternion into a rotation matrix, which is then multiplied with the
- * transform matrix.
- *
- * @return This bone-space joint transform as a matrix. The exact same
- * transform as represented by the position and rotation in this
- * instance, just in matrix form.
- */
- protected Matrix4f getLocalTransform() {
- Matrix4f matrix = new Matrix4f();
- matrix.translate(position);
- Matrix4f.mul(matrix, rotation.toRotationMatrix(), matrix);
- return matrix;
- }
- /**
- * Interpolates between two transforms based on the progression value. The
- * result is a new transform which is part way between the two original
- * transforms. The translation can simply be linearly interpolated, but the
- * rotation interpolation is slightly more complex, using a method called
- * "SLERP" to spherically-linearly interpolate between 2 quaternions
- * (rotations). This gives a much much better result than trying to linearly
- * interpolate between Euler rotations.
- *
- * @param frameA
- * - the previous transform
- * @param frameB
- * - the next transform
- * @param progression
- * - a number between 0 and 1 indicating how far between the two
- * transforms to interpolate. A progression value of 0 would
- * return a transform equal to "frameA", a value of 1 would
- * return a transform equal to "frameB". Everything else gives a
- * transform somewhere in-between the two.
- * @return
- */
- protected static JointTransform interpolate(JointTransform frameA, JointTransform frameB, float progression) {
- Vector3f pos = interpolate(frameA.position, frameB.position, progression);
- Quaternion rot = Quaternion.nlerp(frameA.rotation, frameB.rotation, progression);
- return new JointTransform(pos, rot);
- }
- /**
- * Linearly interpolates between two translations based on a "progression"
- * value.
- *
- * @param start
- * - the start translation.
- * @param end
- * - the end translation.
- * @param progression
- * - a value between 0 and 1 indicating how far to interpolate
- * between the two translations.
- * @return
- */
- private static Vector3f interpolate(Vector3f start, Vector3f end, float progression) {
- float x = start.x + (end.x - start.x) * progression;
- float y = start.y + (end.y - start.y) * progression;
- float z = start.z + (end.z - start.z) * progression;
- return new Vector3f(x, y, z);
- }
- }
|