summaryrefslogtreecommitdiff
path: root/gfx/src/scene/animation_impl.h
blob: 7265858253df9b564a2c5701034dcadedd1f9e78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#pragma once

#include <gfx/scene/animation.h>
#include <gfx/sizes.h>

#include "types.h"

#include <cstring.h>
#include <math/defs.h>
#include <math/mat4.h>
#include <math/quat.h>
#include <math/vec3.h>

#include <stddef.h>
#include <stdint.h>

typedef struct Buffer Buffer;

// Currently ignoring scale in skinning and animation.
//
// TODO: Simultaneous animation of disjoint animations.

/// Skeleton joint.
/// Joints are mutable and store the transform and joint matrices that result
/// from animation, aside from the inverse bind matrix.
typedef struct Joint {
  rel_idx child;           /// First child Joint; index into Anima's joints.
  rel_idx next;            /// Next sibling Joint; index into Anima's joints.
  mat4    transform;       /// Local transform relative to parent.
  mat4    inv_bind_matrix; /// Transforms the mesh into the joint's local space.
  mat4    joint_matrix;    /// inv(global) * global joint transform * inv(bind).
} Joint;

/// Animation skeleton.
typedef struct Skeleton {
  skeleton_idx next;
  size_t       num_joints;
  rel_idx joints[GFX_MAX_NUM_JOINTS]; /// Indices into Anima's joints array.
} Skeleton;

/// A keyframe of animation.
typedef struct Keyframe {
  R time; /// Start time in [0, end animation time]
  union {
    vec3 translation;
    quat rotation;
  };
} Keyframe;

/// Animation channel.
typedef struct Channel {
  rel_idx                target; /// Index into Anima's joints array.
  ChannelType            type;
  AnimationInterpolation interpolation;
  size_t                 num_keyframes;
  Keyframe               keyframes[GFX_MAX_NUM_KEYFRAMES];
} Channel;

/// A skeletal animation.
typedef struct Animation {
  animation_idx next;
  sstring       name;
  R             duration;
  size_t        num_channels;
  Channel       channels[GFX_MAX_NUM_CHANNELS];
} Animation;

/// Animation state.
///
/// This represents the current state of an animation.
typedef struct AnimationState {
  R start_time; // Time when the current animation started playing. -1 means the
                // animation playback has not yet been initialized.
  animation_idx animation; // Current animation. 0 = no animation.
  bool          loop;
} AnimationState;

/// Animation object.
///
/// This is the top-level animation object that encapsulates everything
/// necessary for animation.
///
/// For lack of a better name, this is called an Anima. It is short and the
/// Latin root of animation.
///
/// The last joint of the joints array at index 'num_joints - 1' is the root of
/// all skeletons; specifically, the root of all joints that otherwise would
/// have no parent (a skeleton need not have its own root and can be a set of
/// disjoint node hierarchies).
typedef struct Anima {
  node_idx       parent;     /// Parent SceneNode.
  skeleton_idx   skeleton;   /// Index of first skeleton.
  animation_idx  animation;  /// Index of first animation.
  AnimationState state;      /// Current animation state.
  size_t         num_joints; /// Number of actual joints in the array.
  Joint          joints[GFX_MAX_NUM_JOINTS]; /// Shared by all skeletons.
} Anima;