1 ///
2 module isodi.resource;
3 
4 import core.time;
5 import std.typecons;
6 
7 import rcdata.json;
8 
9 import isodi.pack_list;
10 
11 
12 @safe:
13 
14 
15 /// Defines an object that makes use of some resources, or is a resource itself. It will be signaled every time the
16 /// pack list is updated.
17 interface WithResources {
18 
19     /// Reload the resource's dependencies using the given pack list.
20     ///
21     /// Those dependencies are usually textures, audio files, etc.
22     void reload();
23 
24 }
25 
26 /// Defines an object that uses drawable resources, or is one itself.
27 ///
28 /// Note that some renderers, for example Godot, automatically manage drawing and don't let the user draw manually.
29 /// In this case, the `draw` implementation should be omitted.
30 interface WithDrawableResources : WithResources {
31 
32     /// Draw this resource, if supported by the renderer.
33     void draw();
34 
35 }
36 
37 /// Represents a node in the skeleton.
38 struct SkeletonNode {
39 
40     /// Parent index
41     @JSONExclude
42     size_t parent;
43 
44     /// If true, this node shouldn't be displayed and its bone resource shouldn't be loaded.
45     bool hidden;
46 
47     /// Name of the used bone resource.
48     string name;
49 
50     /// ID of the node, defauls to the bone name. Must be unique, so should be defined in case a bone occurs more than
51     /// one time.
52     string id;
53 
54     /// List of bone variants compatible with this node.
55     ///
56     /// If this is empty, all variants are allowed.
57     string[] variants;
58 
59     /// Offset for the bone's start relative to the parent's end.
60     ///
61     /// If the node is rotated, the whole bone will be rotated relative to this point.
62     float[3] boneStart = [0, 0, 0];
63 
64     /// Position of the bone's end, relative to this node's start.
65     float[3] boneEnd = [0, 0, 0];
66 
67     /// Position of the bone's texture relative to this node's start.
68     float[3] texturePosition = [0, 0, 0];
69 
70     /// Rotation of the node.
71     ushort rotation;
72     invariant(rotation >= 0);
73     invariant(rotation < 360);
74 
75     /// $(TCOLON Bone) If true, the bone textures will be mirrored.
76     bool mirror;
77 
78 }
79 
80 /// Represents a running animation.
81 struct Animation {
82 
83     // Constructor properties
84     public {
85 
86         /// Frames per second.
87         const float fps = 0;
88 
89         /// Amount of times this animation is supposed to play for. 0 for infinite.
90         uint times;
91 
92         /// Parts of the animation.
93         AnimationPart[] parts;
94         // TODO: const?
95 
96     }
97 
98     // Other fields
99     public {
100 
101         /// Current frame.
102         float frame = 0;
103 
104         /// Current part
105         uint current = 0;
106 
107     }
108 
109     /// Continue to the next part of the animation.
110     /// Returns: `Yes.ended` if the animation ended.
111     Flag!"ended" advance() {
112 
113         // Switch to the next part
114         current += 1;
115 
116         // Check if there are more parts
117         if (current < parts.length) return No.ended;
118 
119         // Check for infinite playback
120         if (!times) {
121 
122             // Reset the animation
123             frame = 0;
124             current = 0;
125 
126             return No.ended;
127 
128         }
129 
130         // Check for repeat and advance to the next loop
131         if (--times) return No.ended;
132 
133         // The animation ended
134         return Yes.ended;
135 
136     }
137 
138 }
139 
140 // TODO: Remove the priority field, it just makes the whole process unnecessarily more complex and most likely isn't
141 // needed anyway. Currently it's being ignored anyway.
142 // E: removed from objects, should also be removed from the animation file.
143 
144 /// Represents a single part of the animation, it may be a single or a few frames.
145 struct AnimationPart {
146 
147     /// Length of the part in frames.
148     uint length = 1;
149 
150     /// Change the model offset or position.
151     float[3] offset;
152 
153     /// Apply changes to a bone
154     AnimationBone[string] bone;
155 
156 }
157 
158 /// Changeable bone properties.
159 struct AnimationBone {
160 
161     /// Rotate the bone.
162     float[3] rotate;
163 
164     /// Rotate the bone.
165     float scale;
166 
167 }