summaryrefslogtreecommitdiff
path: root/gfx/include/gfx/scene/animation.h
blob: 42c0c433903f1fe0f4085ccb78a038bcfac098e1 (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#pragma once

#include "node.h"
#include "object.h"
#include <gfx/sizes.h>

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

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

typedef struct Buffer    Buffer;
typedef struct SceneNode SceneNode;

typedef struct Anima    Anima;
typedef struct Joint    Joint;
typedef struct Skeleton Skeleton;

/// Index type used to store relative indices into arrays.
typedef uint16_t rel_idx;

/// Index value denoting no index.
static const rel_idx INDEX_NONE = (rel_idx)-1;

/// Joint descriptor.
typedef struct JointDesc {
  rel_idx parent;          /// Parent Joint; index into Anima's joints.
  mat4    inv_bind_matrix; /// Transforms the mesh into the joint's local space.
} JointDesc;

/// Skeleton descriptor.
typedef struct SkeletonDesc {
  size_t  num_joints;
  rel_idx joints[GFX_MAX_NUM_JOINTS]; /// Indices into Anima's joints array.
} SkeletonDesc;

/// Animation interpolation mode.
typedef enum AnimationInterpolation {
  StepInterpolation,
  LinearInterpolation,
  CubicSplineInterpolation
} AnimationInterpolation;

/// The kind of transformation applied by a Channel.
typedef enum ChannelType {
  RotationChannel,
  ScaleChannel,
  TranslationChannel,
  WeightsChannel
} ChannelType;

/// Animation keyframe descriptor.
///
/// The arrays should have as many entries as 'num_joints' in the SkeletonDesc.
typedef struct KeyframeDesc {
  R time; // Start time in [0, end animation time]
  union {
    vec3 translation;
    quat rotation;
  };
} KeyframeDesc;

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

/// Animation descriptor.
typedef struct AnimationDesc {
  // TODO: Store a name hash for faster comparisons.
  sstring     name;         // Animation name. Required for playback.
  size_t      num_channels; // Number of channels.
  ChannelDesc channels[GFX_MAX_NUM_CHANNELS];
} AnimationDesc;

/// Anima object descriptor.
///
/// The last joint of the joints array at index 'num_joints - 1' must be 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 AnimaDesc {
  size_t        num_skeletons;
  size_t        num_animations;
  size_t        num_joints;
  SkeletonDesc  skeletons[GFX_MAX_NUM_SKELETONS];
  AnimationDesc animations[GFX_MAX_NUM_ANIMATIONS];
  JointDesc     joints[GFX_MAX_NUM_JOINTS];
} AnimaDesc;

/// Animation play settings.
typedef struct AnimationPlaySettings {
  const char* name; // Animation name.
  bool        loop; // Whether to loop the animation or just play once.
  // TODO: Add animation speed.
} AnimationPlaySettings;

/// Create an anima object.
Anima* gfx_make_anima(const AnimaDesc*);

/// Destroy the anima.
void gfx_destroy_anima(Anima**);

/// Play an animation (sets the current animation).
bool gfx_play_animation(Anima*, const AnimationPlaySettings*);

/// Update the current animation.
void gfx_update_animation(Anima*, R t);

/// Stop the current animation.
void gfx_stop_animation(Anima*);

/// Return the anima's ith skeleton.
const Skeleton* gfx_get_anima_skeleton(const Anima* anima, size_t i);